/* ==========================================================================
   Marea Alta - "Open Water" Cinematic Design System
   ========================================================================== */

@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Outfit:wght@400;500;600;700;800&family=Cinzel:wght@500;600;700;800&display=swap');

:root {
    color-scheme: dark;

    --bg-void: #05070b;
    --bg-deep: #0a0d16;
    --card-bg: rgba(20, 20, 28, 0.55);
    --card-bg-solid: rgba(15, 15, 21, 0.94);
    --border-soft: rgba(255, 255, 255, 0.08);
    --border-glow: rgba(156, 43, 78, 0.22);

    --ember: #e8703a;
    --ember-soft: #f2a672;
    --wine: #9c2b4e;
    --frost: #8fc7e8;
    --gold: #e6c065;
    --amber: #ffab3d;
    --amber-soft: #ffd28a;
    --danger: #ff6b60;

    /* Text ramp — every step verified against --bg-void for WCAG AA.
       The old --text-dim (#6f6a60) sat at 3.5:1 and failed outright. */
    --text-main: #f4efe6;   /* ~16.2:1 */
    --text-muted: #b8ada0;  /*  ~8.8:1 */
    --text-dim: #8f8578;    /*  ~5.3:1 */

    --focus-ring: #8fc7e8;

    --shadow-glow: 0 0 20px rgba(232, 112, 58, 0.14);
    --shadow-btn: 0 0 15px rgba(232, 112, 58, 0.3);

    --radius-sm: 8px;
    --radius-md: 14px;
    --radius-lg: 22px;

    --ease-pop: cubic-bezier(.18, .89, .32, 1.28);
    --ease-smooth: cubic-bezier(.4, 0, .2, 1);

    /* Overwritten by settings.js */
    --text-scale: 100;
    --line-base: 1.6;
}

/* User text-size preference. Type that matters is expressed in rem below so
   this actually moves it, rather than only affecting stray unstyled text. */
html {
    font-size: calc(16px * var(--text-scale) / 100);
}

* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

::selection {
    background: var(--ember);
    color: #fff;
}

body {
    background-color: var(--bg-void);
    color: var(--text-main);
    font-family: 'Inter', sans-serif;
    line-height: 1.6;
    height: 100vh;
    overflow: hidden;
    position: relative;
    background-image:
        radial-gradient(circle at 12% 15%, rgba(156, 43, 78, 0.10) 0%, transparent 42%),
        radial-gradient(circle at 88% 12%, rgba(143, 199, 232, 0.08) 0%, transparent 40%),
        radial-gradient(circle at 50% 100%, rgba(255, 171, 61, 0.07) 0%, transparent 55%),
        linear-gradient(180deg, var(--bg-void) 0%, var(--bg-deep) 100%);
    background-attachment: fixed;
}

/* Subtle cinematic film-grain + vignette overlay, purely decorative */
body::before {
    content: "";
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 4000;
    background: radial-gradient(ellipse at center, transparent 55%, rgba(0, 0, 0, 0.55) 100%);
    mix-blend-mode: multiply;
}

body::after {
    content: "";
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 4001;
    opacity: 0.035;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
    mix-blend-mode: overlay;
}

#app {
    display: grid;
    grid-template-columns: 350px 1fr;
    grid-template-rows: 72px 1fr;
    height: 100vh;
    width: 100vw;
    position: relative;
    z-index: 2;
    /* `both`, not `opacity:0` + `forwards`. The old pairing made the game
       visible ONLY while this animation existed — so "Animation: None" and
       "Screen shake: off" (both of which null out animation-name) left the
       whole app stuck at opacity 0, i.e. a blank screen. */
    animation: appReveal 0.7s var(--ease-smooth) 0.15s both;
}

@keyframes appReveal {
    from { opacity: 0; transform: scale(0.99); }
    to   { opacity: 1; transform: scale(1); }
}

header {
    grid-column: 1 / span 2;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 24px;
    background: rgba(10, 9, 16, 0.82);
    backdrop-filter: blur(14px);
    border-bottom: 1px solid rgba(255, 255, 255, 0.07);
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0.35);
    z-index: 100;
    position: relative;
}

header::after {
    content: "";
    position: absolute;
    left: 0; right: 0; bottom: -1px;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--ember), var(--wine), var(--frost), transparent);
    opacity: 0.6;
}

h1 {
    font-family: 'Cinzel', serif;
    font-size: 19px;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    /* Static gradient. The old version shimmered on a 10s infinite loop, which
       read as a screensaver rather than a masthead. */
    background: linear-gradient(100deg, var(--amber-soft), var(--ember) 45%, var(--wine));
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    cursor: pointer;
    white-space: nowrap;
    transition: filter 0.25s ease;
    user-select: none;
}

h1:hover {
    filter: brightness(1.18) drop-shadow(0 0 12px rgba(232, 112, 58, 0.4));
}

.stats-bar {
    display: flex;
    align-items: center;
    gap: 14px;
    font-family: 'Outfit', sans-serif;
}

/* Instrument cluster: one housing, hairline-divided cells — instead of five
   free-floating "Label: 0" pills. */
.stat-cluster {
    display: flex;
    align-items: stretch;
    border: 1px solid rgba(255, 255, 255, 0.09);
    border-radius: 12px;
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.02));
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06);
    overflow: hidden;
}

.stat-pill {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1px;
    min-width: 68px;
    padding: 6px 14px;
    transition: background 0.25s ease;
}

.stat-pill + .stat-pill {
    border-left: 1px solid rgba(255, 255, 255, 0.07);
}

.stat-pill:hover {
    background: rgba(255, 255, 255, 0.05);
}

.stat-key {
    font-size: 9px;
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    white-space: nowrap;
    color: var(--text-dim);
}

.stat-val {
    font-size: 15px;
    font-weight: 700;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
    color: var(--text-main);
}

.header-tools {
    display: flex;
    gap: 8px;
}

/* ==========================================================================
   Sidebar Panel
   ========================================================================== */
aside {
    background: rgba(10, 9, 16, 0.55);
    border-right: 1px solid rgba(255, 255, 255, 0.05);
    padding: 20px;
    display: flex;
    flex-direction: column;
    gap: 18px;
    overflow-y: auto;
    backdrop-filter: blur(14px);
    position: relative;
}

.aside-title {
    font-family: 'Outfit', sans-serif;
    font-size: 13px;
    text-transform: uppercase;
    letter-spacing: 2px;
    color: var(--text-muted);
    border-bottom: 1px solid rgba(255, 255, 255, 0.07);
    padding-bottom: 10px;
    display: flex;
    align-items: center;
    gap: 8px;
}

.aside-title::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--ember);
    box-shadow: 0 0 8px var(--ember);
    animation: dotPulse 1.8s ease-in-out infinite;
}

@keyframes dotPulse {
    0%, 100% { opacity: 0.4; transform: scale(0.8); }
    50% { opacity: 1; transform: scale(1.15); }
}

#sidebarPlayers {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.sidebar-player-card {
    background: var(--card-bg);
    border-radius: var(--radius-md);
    padding: 14px;
    border: 1px solid rgba(255, 255, 255, 0.04);
    box-shadow: var(--shadow-glow);
    transition: transform 0.25s var(--ease-pop), box-shadow 0.25s ease, border-color 0.25s ease;
    position: relative;
    overflow: hidden;
    opacity: 0;
    transform: translateX(-8px);
    animation: cardSlideIn 0.45s var(--ease-pop) forwards;
    animation-delay: calc(var(--i, 0) * 0.06s);
}

@keyframes cardSlideIn {
    to { opacity: 1; transform: translateX(0); }
}

.sidebar-player-card:hover {
    transform: translateY(-3px);
    box-shadow: 0 8px 28px rgba(156, 43, 78, 0.3);
    border-color: rgba(255, 255, 255, 0.1);
}

.player-name-row {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 10px;
}

.player-avatar {
    flex-shrink: 0;
    width: 46px;
    height: 46px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Outfit', sans-serif;
    font-weight: 800;
    font-size: 15px;
    color: #060509;
    background: var(--avatar-color, #fff);
    box-shadow: 0 0 12px var(--avatar-color, rgba(255, 255, 255, 0.4));
    text-shadow: none;
    overflow: hidden;
    border: 2px solid var(--avatar-color, rgba(255, 255, 255, 0.6));
}

.avatar-face {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center top;
    border-radius: 50%;
}

.player-name-col {
    display: flex;
    flex-direction: column;
    line-height: 1.25;
    flex: 1;
    min-width: 0;
}

.player-name-lbl {
    font-family: 'Outfit', sans-serif;
    font-size: 15.5px;
    font-weight: 700;
}

.player-relation-lbl {
    font-size: 11px;
    color: var(--text-muted);
}

.player-stat-bar-row {
    margin-top: 8px;
}

.bar-lbl {
    display: flex;
    justify-content: space-between;
    font-size: 11px;
    color: var(--text-muted);
    margin-bottom: 3px;
}

.bar-lbl span {
    font-weight: 700;
    color: var(--text-main);
}

.bar-outer {
    background: rgba(255, 255, 255, 0.06);
    height: 7px;
    border-radius: 4px;
    overflow: hidden;
    position: relative;
}

.bar-inner {
    height: 100%;
    border-radius: 4px;
    transition: width 0.5s var(--ease-smooth);
    position: relative;
    overflow: hidden;
}

.bar-inner::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.45), transparent);
    width: 40%;
    animation: barShimmer 2.4s linear infinite;
}

@keyframes barShimmer {
    0% { transform: translateX(-120%); }
    100% { transform: translateX(320%); }
}

.corr-bar {
    background: linear-gradient(90deg, var(--ember), var(--wine));
}

.rel-bar {
    background: linear-gradient(90deg, var(--frost), var(--wine));
}

.status-badge {
    display: inline-block;
    font-size: 10px;
    font-weight: 700;
    padding: 3px 9px;
    border-radius: 5px;
    margin-top: 8px;
    letter-spacing: 0.3px;
}

.pregnant-badge {
    background: rgba(232, 112, 58, 0.15);
    color: var(--ember);
    border: 1px solid rgba(232, 112, 58, 0.3);
    animation: badgeGlow 2s ease-in-out infinite;
}

@keyframes badgeGlow {
    0%, 100% { box-shadow: 0 0 0 rgba(232, 112, 58, 0); }
    50% { box-shadow: 0 0 10px rgba(232, 112, 58, 0.45); }
}

.badge {
    font-size: 11px;
    font-weight: bold;
    padding: 3px 10px;
    border-radius: 12px;
}

.rival-badge {
    background: rgba(255, 51, 51, 0.15);
    color: #ff3333;
    border: 1px solid rgba(255, 51, 51, 0.3);
}

.neutral-badge {
    background: rgba(255, 255, 255, 0.05);
    color: var(--text-muted);
}

.sidebar-controls {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
    margin-top: auto;
    padding-top: 6px;
}

/* ==========================================================================
   Main Arena Content Layout
   ========================================================================== */
main {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    position: relative;
}

.tabs-navigation {
    display: flex;
    background: rgba(10, 9, 16, 0.35);
    border-bottom: 1px solid rgba(255, 255, 255, 0.05);
    padding: 0 20px;
    gap: 8px;
    min-height: 50px;
    align-items: flex-end;
    position: relative;
}

.tab-btn {
    background: none;
    border: none;
    color: var(--text-muted);
    font-family: 'Outfit', sans-serif;
    font-size: 14px;
    font-weight: 600;
    padding: 12px 20px;
    cursor: pointer;
    border-bottom: 3px solid transparent;
    transition: color 0.2s ease;
    position: relative;
}

.tab-btn:hover {
    color: var(--text-main);
}

.tab-btn.active {
    color: var(--ember);
}

.tab-slider {
    position: absolute;
    bottom: -1px;
    height: 3px;
    border-radius: 3px 3px 0 0;
    background: linear-gradient(90deg, var(--ember), var(--wine));
    box-shadow: 0 0 10px rgba(232, 112, 58, 0.6);
    transition: left 0.32s var(--ease-pop), width 0.32s var(--ease-pop);
    pointer-events: none;
}

.panel-content {
    flex: 1;
    overflow-y: auto;
    padding: 24px;
    animation: panelFadeIn 0.35s var(--ease-smooth);
}

@keyframes panelFadeIn {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* ==========================================================================
   Gameplay Panel Elements
   ========================================================================== */
.play-layout {
    display: grid;
    grid-template-columns: 320px 1fr;
    gap: 24px;
    height: 100%;
}

/* ==========================================================================
   The Bowl of Fate — ticket draw mechanic (replaces the fortune wheel)
   ========================================================================== */
.draw-section {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
}

#drawStage {
    position: relative;
    width: 260px;
    height: 260px;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    perspective: 900px;
}

/* --- Fate bowl --- */
#fateBowl {
    position: relative;
    width: 210px;
    height: 150px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    transform-origin: 50% 90%;
}

#fateBowl.rattling {
    animation: bowlRattle 0.6s ease-in-out;
}

@keyframes bowlRattle {
    0%, 100% { transform: rotate(0) translateX(0); }
    15% { transform: rotate(-3deg) translateX(-4px); }
    30% { transform: rotate(3deg) translateX(4px); }
    45% { transform: rotate(-2.4deg) translateX(-3px); }
    60% { transform: rotate(2deg) translateX(3px); }
    80% { transform: rotate(-1deg) translateX(-1px); }
}

.bowl-halo {
    position: absolute;
    bottom: 6px;
    width: 200px;
    height: 110px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(230, 192, 101, 0.2), transparent 66%);
    filter: blur(16px);
    z-index: 0;
    animation: haloPulse 4s ease-in-out infinite;
}

@keyframes haloPulse {
    0%, 100% { opacity: 0.5; transform: scale(1); }
    50% { opacity: 0.9; transform: scale(1.08); }
}

.bowl-body {
    position: relative;
    width: 190px;
    height: 112px;
    z-index: 2;
    border-radius: 0 0 95px 95px / 0 0 78px 78px;
    background:
        radial-gradient(ellipse at 50% -30%, rgba(230, 192, 101, 0.10), transparent 55%),
        linear-gradient(180deg, rgba(24, 28, 44, 0.75), rgba(10, 12, 22, 0.9) 75%);
    border: 1px solid rgba(230, 192, 101, 0.35);
    border-top: 2.5px solid var(--gold);
    box-shadow:
        inset 0 -22px 36px rgba(0, 0, 0, 0.55),
        inset 0 6px 18px rgba(230, 192, 101, 0.08),
        0 16px 34px rgba(0, 0, 0, 0.5),
        0 0 24px rgba(230, 192, 101, 0.12);
    overflow: hidden;
}

.bowl-glass {
    position: absolute;
    inset: 0;
    background: linear-gradient(115deg, rgba(255, 255, 255, 0.07) 4%, transparent 34%);
    pointer-events: none;
}

/* slim curved highlight along the inner-left wall (no more grey blob) */
.bowl-shine {
    position: absolute;
    top: 10px;
    left: 14px;
    width: 8px;
    height: 62px;
    border-radius: 50%;
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.28), transparent 85%);
    filter: blur(2px);
    transform: rotate(20deg);
    pointer-events: none;
}

.bowl-base {
    width: 74px;
    height: 12px;
    margin-top: -2px;
    z-index: 1;
    border-radius: 0 0 8px 8px;
    background: linear-gradient(180deg, rgba(230, 192, 101, 0.5), rgba(60, 46, 18, 0.9));
    box-shadow: 0 6px 14px rgba(0, 0, 0, 0.5);
}

.bowl-caption {
    margin-top: 12px;
    font-family: 'Cinzel', serif;
    font-size: 12px;
    letter-spacing: 3px;
    text-transform: uppercase;
    color: var(--gold);
    opacity: 0.85;
    text-shadow: 0 0 10px rgba(230, 192, 101, 0.45);
}

/* Folded tickets bobbing inside the bowl */
.bowl-tickets {
    position: absolute;
    inset: 0;
    z-index: 3;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
}

.folded-ticket {
    position: absolute;
    bottom: 18px;
    left: calc(50% + var(--tx, 0));
    width: 24px;
    height: 16px;
    border-radius: 3px;
    background:
        linear-gradient(180deg, #f7ecd6, #d9c39a);
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.4), inset 0 0 0 1px rgba(120, 90, 50, 0.25);
    transform: translateX(-50%) rotate(var(--r, 0));
    animation: ticketBob 3.2s ease-in-out infinite;
    animation-delay: var(--d, 0s);
}

.folded-ticket::after {
    content: "";
    position: absolute;
    top: 0; left: 50%;
    width: 1px; height: 100%;
    background: rgba(120, 90, 50, 0.35);
}

#fateBowl.rattling .folded-ticket {
    animation: ticketShuffle 0.6s ease-in-out;
}

@keyframes ticketBob {
    0%, 100% { transform: translateX(-50%) rotate(var(--r, 0)) translateY(0); }
    50% { transform: translateX(-50%) rotate(var(--r, 0)) translateY(-4px); }
}

@keyframes ticketShuffle {
    0%, 100% { transform: translateX(-50%) rotate(var(--r, 0)); }
    25% { transform: translateX(calc(-50% - 6px)) rotate(calc(var(--r) + 20deg)) translateY(-6px); }
    50% { transform: translateX(calc(-50% + 8px)) rotate(calc(var(--r) - 16deg)) translateY(-3px); }
    75% { transform: translateX(calc(-50% - 3px)) rotate(calc(var(--r) + 8deg)); }
}

/* --- The reveal ticket (flies out & unfolds) --- */
.reveal-ticket {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 20;
    pointer-events: none;
    opacity: 0;
    visibility: hidden;
    perspective: 1000px;
}

.reveal-ticket.active {
    visibility: visible;
    opacity: 1;
}

.rt-card {
    position: relative;
    width: 210px;
    height: 130px;
    transform-style: preserve-3d;
    transform: translateY(70px) scale(0.25) rotate(-14deg);
    opacity: 0;
}

.reveal-ticket.emerging .rt-card {
    animation: ticketEmerge 0.62s cubic-bezier(.2,.8,.25,1.2) forwards;
}

@keyframes ticketEmerge {
    0%   { transform: translateY(70px) scale(0.25) rotate(-16deg); opacity: 0; }
    55%  { opacity: 1; }
    100% { transform: translateY(0) scale(1) rotate(0deg); opacity: 1; }
}

.reveal-ticket.settled .rt-card {
    transform: translateY(0) scale(1) rotate(0deg);
    opacity: 1;
}

.reveal-ticket.dismiss .rt-card {
    animation: ticketDismiss 0.42s ease-in forwards;
}

@keyframes ticketDismiss {
    0%   { transform: translateY(0) scale(1) rotate(0); opacity: 1; }
    100% { transform: translateY(-60px) scale(0.7) rotate(8deg); opacity: 0; }
}

/* The revealed body under the flaps */
.rt-body {
    position: absolute;
    inset: 0;
    border-radius: 12px;
    background:
        radial-gradient(circle at 50% 0%, rgba(255, 255, 255, 0.08), transparent 60%),
        linear-gradient(155deg, #1a1526, #241a2e 55%, #120e1c);
    border: 1px solid var(--rt-color, var(--ember));
    box-shadow: 0 18px 40px rgba(0, 0, 0, 0.6), inset 0 0 26px rgba(0,0,0,0.5), 0 0 26px var(--rt-color, var(--ember));
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    overflow: hidden;
}

.rt-body::before {
    content: "";
    position: absolute;
    inset: 5px;
    border-radius: 8px;
    border: 1px dashed rgba(255, 255, 255, 0.14);
    pointer-events: none;
}

.rt-role {
    font-family: 'Cinzel', serif;
    font-size: 10px;
    letter-spacing: 3px;
    text-transform: uppercase;
    color: var(--text-muted);
    opacity: 0;
    transform: translateY(6px);
}

.rt-name {
    font-family: 'Outfit', sans-serif;
    font-size: 30px;
    font-weight: 800;
    letter-spacing: 0.5px;
    color: var(--rt-color, #fff);
    text-shadow: 0 0 18px var(--rt-color, rgba(255,255,255,0.4));
    opacity: 0;
    transform: scale(0.7);
}

.rt-relation {
    font-size: 11px;
    color: var(--text-muted);
    opacity: 0;
    transform: translateY(6px);
}

.reveal-ticket.open .rt-role { animation: rtTextIn 0.4s ease 0.18s forwards; }
.reveal-ticket.open .rt-name { animation: rtNameIn 0.5s var(--ease-pop) 0.24s forwards; }
.reveal-ticket.open .rt-relation { animation: rtTextIn 0.4s ease 0.34s forwards; }

@keyframes rtTextIn {
    to { opacity: 1; transform: translateY(0); }
}
@keyframes rtNameIn {
    to { opacity: 1; transform: scale(1); }
}

/* Wax seal stamp */
.rt-seal {
    position: absolute;
    bottom: 8px;
    right: 10px;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: radial-gradient(circle at 35% 30%, var(--rt-color, var(--wine)), #4a0d20 80%);
    color: rgba(255, 255, 255, 0.85);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.6);
    opacity: 0;
    transform: scale(2.4) rotate(-20deg);
}

.reveal-ticket.sealed .rt-seal {
    animation: sealStamp 0.4s var(--ease-pop) forwards;
}

@keyframes sealStamp {
    0%   { opacity: 0; transform: scale(2.4) rotate(-20deg); }
    60%  { opacity: 1; transform: scale(0.86) rotate(4deg); }
    100% { opacity: 1; transform: scale(1) rotate(0); }
}

/* The two paper flaps covering the ticket while folded */
.rt-flap {
    position: absolute;
    left: 0;
    width: 100%;
    height: 50%;
    z-index: 5;
    background:
        repeating-linear-gradient(180deg, rgba(0,0,0,0.03) 0 3px, transparent 3px 6px),
        linear-gradient(180deg, #f4e8cf, #dcc59a);
    backface-visibility: hidden;
    box-shadow: inset 0 0 0 1px rgba(120, 90, 50, 0.3);
}

.rt-flap-top {
    top: 0;
    transform-origin: bottom center;
    border-radius: 12px 12px 2px 2px;
    box-shadow: inset 0 0 0 1px rgba(120, 90, 50, 0.3), 0 2px 4px rgba(0,0,0,0.3);
}

.rt-flap-bottom {
    bottom: 0;
    transform-origin: top center;
    border-radius: 2px 2px 12px 12px;
}

/* crease line down the fold */
.rt-flap-top::after,
.rt-flap-bottom::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 0;
    width: 1px;
    height: 100%;
    background: rgba(120, 90, 50, 0.28);
}

.reveal-ticket.open .rt-flap-top {
    transform: rotateX(168deg);
    transition: transform 0.55s cubic-bezier(.4,0,.2,1);
    box-shadow: 0 -10px 20px rgba(0,0,0,0.4);
}

.reveal-ticket.open .rt-flap-bottom {
    transform: rotateX(-168deg);
    transition: transform 0.55s cubic-bezier(.4,0,.2,1);
    box-shadow: 0 10px 20px rgba(0,0,0,0.4);
}

.arena-section {
    display: flex;
    flex-direction: column;
    gap: 20px;
    background: rgba(20, 18, 32, 0.35);
    border-radius: var(--radius-lg);
    border: 1px solid rgba(255, 255, 255, 0.05);
    padding: 22px;
    min-height: 500px;
    box-shadow: 0 20px 50px rgba(0, 0, 0, 0.25);
    position: relative;
}

#roundTitle {
    font-family: 'Outfit', sans-serif;
    font-size: 19px;
    font-weight: 700;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
    padding-bottom: 12px;
    letter-spacing: 0.2px;
}

.glow-txt-cyan {
    color: var(--frost);
    text-shadow: 0 0 12px rgba(143, 199, 232, 0.7);
    animation: textPulse 1s ease-in-out infinite;
}

.glow-txt-pink {
    color: var(--ember);
    text-shadow: 0 0 12px rgba(232, 112, 58, 0.7);
    animation: textPulse 1s ease-in-out infinite;
}

@keyframes textPulse {
    0%, 100% { opacity: 0.75; }
    50% { opacity: 1; }
}

.arena-body {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

/* Action Box Group styling */
.action-box-group {
    background: rgba(255, 255, 255, 0.02);
    border-radius: 12px;
    padding: 14px;
    border: 1px solid rgba(255, 255, 255, 0.05);
    animation: panelFadeIn 0.3s var(--ease-smooth);
}

.action-box-title {
    font-family: 'Outfit', sans-serif;
    font-size: 12.5px;
    text-transform: uppercase;
    letter-spacing: 1.2px;
    color: var(--frost);
    margin-bottom: 10px;
    font-weight: bold;
}

.action-box-flex {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

/* Speech bubbles and narrative formatting */
.speech-bubble {
    background: rgba(255, 255, 255, 0.035);
    border-radius: 12px;
    padding: 12px 16px;
    animation: bubbleFadeIn 0.35s var(--ease-pop) forwards;
    position: relative;
}

.bubble-name {
    font-family: 'Outfit', sans-serif;
    font-weight: 700;
    font-size: 13px;
    margin-bottom: 4px;
}

.bubble-text {
    font-size: 14px;
    font-style: italic;
    color: #dedbe6;
}

.narrative-line {
    font-size: 13.5px;
    color: var(--text-muted);
    padding: 5px 10px;
    border-left: 2px solid rgba(255, 255, 255, 0.1);
    animation: panelFadeIn 0.3s var(--ease-smooth);
}

.auto-thinking {
    color: var(--amber-soft);
    font-style: italic;
    position: relative;
}

.auto-thinking::after {
    content: "";
    display: inline-block;
    width: 4px;
    height: 4px;
    margin-left: 6px;
    border-radius: 50%;
    background: var(--amber-soft);
    box-shadow: 8px 0 0 0 var(--amber-soft), 16px 0 0 0 var(--amber-soft);
    animation: thinkingDots 1.1s ease-in-out infinite;
}

@keyframes thinkingDots {
    0%, 100% { opacity: 0.25; }
    50% { opacity: 1; }
}

.text-speech-line {
    font-size: 13.5px;
    padding: 8px 4px;
}

.visual-image-wrapper {
    max-width: 100%;
    margin: 12px auto;
    border-radius: 14px;
    overflow: hidden;
    border: 1px solid rgba(255, 255, 255, 0.08);
    box-shadow: 0 14px 40px rgba(0, 0, 0, 0.55);
    animation: imagePop 0.45s var(--ease-pop) forwards;
    position: relative;
}

.visual-image-wrapper::after {
    content: "";
    position: absolute;
    inset: 0;
    box-shadow: inset 0 -40px 40px -20px rgba(0, 0, 0, 0.55);
    pointer-events: none;
}

.scene-visual-img {
    display: block;
    max-width: 100%;
    max-height: 400px;
    object-fit: contain;
    margin: 0 auto;
}

/* ==========================================================================
   Buttons and Inputs
   ========================================================================== */
.nav-btn, .action-btn, .gallery-btn {
    font-family: 'Outfit', sans-serif;
    font-weight: bold;
    cursor: pointer;
    border: none;
    border-radius: var(--radius-sm);
    transition: all 0.2s var(--ease-smooth);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    position: relative;
    overflow: hidden;
}

.nav-btn {
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.1);
    color: var(--text-main);
    padding: 9px 16px;
    font-size: 13px;
}

.nav-btn:hover:not(:disabled) {
    background: rgba(255, 255, 255, 0.1);
    border-color: rgba(255, 255, 255, 0.2);
    transform: translateY(-1px);
}

.nav-btn:active:not(:disabled), .action-btn:active:not(:disabled), .btn-harem:active:not(:disabled), .btn-marry:active:not(:disabled) {
    transform: scale(0.96) !important;
}

.btn-marry {
    background: linear-gradient(135deg, var(--gold), #b5852f);
    color: #241a08;
    border: none;
}

.btn-marry:hover:not(:disabled) {
    box-shadow: 0 0 16px rgba(230, 192, 101, 0.5);
    transform: scale(1.03);
}

.btn-harem {
    background: linear-gradient(135deg, var(--ember), var(--wine));
    color: #ffffff;
    box-shadow: var(--shadow-btn);
}

.btn-harem:hover:not(:disabled) {
    box-shadow: 0 0 28px rgba(232, 112, 58, 0.65);
    transform: scale(1.03);
}

.btn-harem:disabled, .nav-btn:disabled, .action-btn:disabled {
    opacity: 0.45;
    cursor: not-allowed;
    transform: none !important;
}

.action-btn {
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid rgba(255, 255, 255, 0.06);
    color: var(--frost);
    padding: 10px 14px;
    font-size: 13px;
    border-radius: 8px;
}

.action-btn:hover:not(:disabled) {
    background: rgba(143, 199, 232, 0.1);
    border-color: var(--frost);
    color: #ffffff;
    transform: translateY(-2px);
    box-shadow: 0 6px 18px rgba(143, 199, 232, 0.2);
}

.req-badge {
    background: rgba(255, 255, 255, 0.07);
    padding: 2px 6px;
    border-radius: 4px;
    font-size: 10px;
    color: var(--text-muted);
    margin-left: 6px;
}

.btn-danger-glow {
    color: var(--ember) !important;
    border-color: rgba(232, 112, 58, 0.3) !important;
}

.btn-danger-glow:hover:not(:disabled) {
    background: rgba(232, 112, 58, 0.15) !important;
    border-color: var(--ember) !important;
    color: #fff !important;
}

.finish-choice-box {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    background: rgba(232, 112, 58, 0.04);
    border: 1px solid rgba(232, 112, 58, 0.18);
    border-radius: var(--radius-md);
    padding: 16px;
    animation: panelFadeIn 0.3s var(--ease-smooth);
}

.scene-hold-indicator {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    padding: 14px 16px;
    border-radius: var(--radius-md);
    border: 1px solid rgba(255, 255, 255, 0.06);
    background: rgba(255, 255, 255, 0.02);
    animation: panelFadeIn 0.3s var(--ease-smooth);
}

.finish-choice-box h3 {
    font-family: 'Outfit', sans-serif;
    font-size: 14px;
    width: 100%;
    margin-bottom: 4px;
    color: var(--ember-soft);
}

/* ==========================================================================
   Modals
   ========================================================================== */
.modal-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    background: rgba(4, 3, 8, 0.82);
    backdrop-filter: blur(16px);
    z-index: 1000;
    display: none; /* Flex when active */
    justify-content: center;
    align-items: center;
    padding: 20px;
    animation: overlayFade 0.3s var(--ease-smooth);
}

@keyframes overlayFade {
    from { background: rgba(4, 3, 8, 0); backdrop-filter: blur(0); }
    to   { background: rgba(4, 3, 8, 0.82); backdrop-filter: blur(16px); }
}

.modal-card {
    background: var(--card-bg-solid);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: var(--radius-lg);
    max-width: 650px;
    width: 100%;
    max-height: 90vh;
    overflow-y: auto;
    padding: 32px;
    box-shadow: 0 30px 70px rgba(156, 43, 78, 0.25), 0 0 0 1px rgba(255, 255, 255, 0.02);
    text-align: center;
    animation: modalSlideUp 0.4s var(--ease-pop) forwards;
    position: relative;
}

.modal-card::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: var(--radius-lg);
    padding: 1px;
    background: linear-gradient(135deg, var(--ember), transparent 30%, transparent 70%, var(--frost));
    -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    opacity: 0.5;
    pointer-events: none;
}

.modal-card h2 {
    font-family: 'Outfit', sans-serif;
    font-size: 23px;
    margin-bottom: 16px;
    letter-spacing: 0.2px;
}

.modal-media {
    display: flex;
    justify-content: center;
}

.modal-img {
    max-width: 100%;
    max-height: 300px;
    border-radius: 14px;
    margin: 16px 0;
    box-shadow: 0 16px 34px rgba(0, 0, 0, 0.5);
}

.modal-desc {
    color: var(--text-muted);
    font-size: 15px;
    margin-bottom: 26px;
}

@keyframes modalSlideUp {
    0% {
        opacity: 0;
        transform: translateY(30px) scale(0.97);
    }
    100% {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

/* Confetti burst for celebratory endings */
#confettiLayer {
    position: fixed;
    inset: 0;
    z-index: 1100;
    pointer-events: none;
    overflow: hidden;
}

.confetti-piece {
    position: absolute;
    top: -5vh;
    left: var(--x, 50%);
    width: var(--w, 8px);
    height: var(--w, 8px);
    background: var(--c, var(--ember));
    border-radius: 2px;
    opacity: 0.9;
    animation: confettiFall var(--dur, 3s) ease-in forwards;
    animation-delay: var(--delay, 0s);
}

@keyframes confettiFall {
    0% { transform: translate3d(0, -5vh, 0) rotate(0deg); opacity: 1; }
    100% { transform: translate3d(var(--drift, 80px), 105vh, 0) rotate(600deg); opacity: 0; }
}

/* Screen flash for dramatic beats (impregnation, etc.) */
#flashOverlay {
    position: fixed;
    inset: 0;
    z-index: 1050;
    pointer-events: none;
    background: radial-gradient(circle at 50% 50%, rgba(232, 112, 58, 0.35), transparent 70%);
    opacity: 0;
}

#flashOverlay.active {
    animation: flashPulse 0.9s ease-out;
}

@keyframes flashPulse {
    0% { opacity: 0; }
    15% { opacity: 1; }
    100% { opacity: 0; }
}

/* ==========================================================================
   Gallery Panel
   ========================================================================== */
.gallery-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 20px;
}

.gallery-card {
    background: var(--card-bg);
    border-radius: 16px;
    padding: 20px;
    border: 1px solid rgba(255, 255, 255, 0.04);
    box-shadow: var(--shadow-glow);
    display: flex;
    flex-direction: column;
    gap: 12px;
    transition: transform 0.25s var(--ease-pop), box-shadow 0.25s ease;
}

.gallery-card:hover {
    transform: translateY(-4px);
    box-shadow: 0 14px 34px rgba(156, 43, 78, 0.28);
}

.gallery-card h3 {
    font-family: 'Outfit', sans-serif;
    font-size: 18px;
    margin-bottom: 0;
}

.gallery-card-head {
    display: flex;
    align-items: center;
    gap: 12px;
}

.gallery-face {
    display: block;
    flex-shrink: 0;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    object-fit: cover;
    object-position: center top;
    box-shadow: 0 0 14px rgba(255, 255, 255, 0.15);
    border: 2px solid rgba(255, 255, 255, 0.18);
}

.gallery-btn {
    padding: 12px;
    font-size: 13px;
    width: 100%;
}

.gallery-btn.unlocked {
    background: rgba(143, 199, 232, 0.1);
    border: 1px solid var(--frost);
    color: #ffffff;
}

.gallery-btn.unlocked:hover {
    background: var(--frost);
    color: #000;
    box-shadow: 0 0 18px rgba(143, 199, 232, 0.5);
}

.gallery-btn.locked {
    background: rgba(255, 255, 255, 0.02);
    border: 1px solid rgba(255, 255, 255, 0.05);
    color: var(--text-muted);
    cursor: not-allowed;
}

/* ==========================================================================
   Achievements Items
   ========================================================================== */
.achievement-item {
    display: grid;
    grid-template-columns: 2fr 1fr 1fr;
    align-items: center;
    padding: 11px 16px;
    background: rgba(255, 255, 255, 0.02);
    border-radius: 8px;
    border: 1px solid rgba(255, 255, 255, 0.05);
    margin-bottom: 8px;
    gap: 8px;
    transition: border-color 0.2s ease;
}

.achievement-item:hover {
    border-color: rgba(156, 43, 78, 0.3);
}

.ach-name {
    font-family: 'Outfit', sans-serif;
    font-weight: 700;
    text-align: left;
}

.ach-badge {
    font-size: 11px;
    font-weight: bold;
    padding: 4px 0;
    border-radius: 4px;
}

.ach-badge.unlocked {
    background: rgba(230, 192, 101, 0.15);
    color: var(--gold);
    border: 1px solid rgba(230, 192, 101, 0.3);
}

.ach-badge.locked {
    background: rgba(255, 255, 255, 0.03);
    color: var(--text-muted);
    border: 1px solid rgba(255, 255, 255, 0.05);
}

/* ==========================================================================
   Cheats Panel
   ========================================================================== */
.cheat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 20px;
}

.cheat-card {
    background: rgba(255, 51, 51, 0.02);
    border: 1px solid rgba(255, 51, 51, 0.1);
    border-radius: 16px;
    padding: 20px;
    box-shadow: 0 0 20px rgba(255, 51, 51, 0.05);
}

.cheat-card h3 {
    font-family: 'Outfit', sans-serif;
    font-size: 16px;
    color: #ff5555;
    margin-bottom: 12px;
}

.cheat-control {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.cheat-select, .cheat-input {
    background: rgba(0, 0, 0, 0.3);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 6px;
    padding: 8px;
    color: var(--text-main);
    font-family: inherit;
    font-size: 13px;
}

.cheat-btn {
    background: rgba(255, 51, 51, 0.1);
    border: 1px solid rgba(255, 51, 51, 0.3);
    color: #ffdddd;
    padding: 8px;
    border-radius: 6px;
    font-weight: bold;
    cursor: pointer;
    transition: all 0.2s;
}

.cheat-btn:hover {
    background: #ff3333;
    color: #fff;
    box-shadow: 0 0 10px rgba(255, 51, 51, 0.4);
}

/* ==========================================================================
   Persistent Logs Tab
   ========================================================================== */
.persistent-log-entry {
    font-family: 'JetBrains Mono', 'Courier New', monospace;
    font-size: 12.5px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.03);
    padding: 7px 4px;
}

.persistent-log-entry:hover {
    background: rgba(255, 255, 255, 0.02);
}

.log-timestamp {
    color: var(--frost);
}

/* ==========================================================================
   Animations
   ========================================================================== */
@keyframes bubbleFadeIn {
    0% {
        opacity: 0;
        transform: scale(0.95) translateY(10px);
    }
    100% {
        opacity: 1;
        transform: scale(1.0) translateY(0);
    }
}

@keyframes imagePop {
    0% {
        opacity: 0;
        transform: scale(0.97);
    }
    100% {
        opacity: 1;
        transform: scale(1.0);
    }
}

/* Floating Number Effect */
.floating-indicator {
    position: absolute;
    transform: translate(-50%, -50%);
    font-family: 'Outfit', sans-serif;
    font-weight: 800;
    font-size: 15px;
    padding: 8px 18px;
    border-radius: 100px;
    pointer-events: none;
    z-index: 10000;
    background: rgba(10, 9, 16, 0.85);
    border: 1px solid currentColor;
    backdrop-filter: blur(6px);
    animation: floatUp 1.4s var(--ease-pop) forwards;
    white-space: nowrap;
}

.floating-corruption {
    color: var(--ember);
    box-shadow: 0 0 18px rgba(232, 112, 58, 0.5);
    text-shadow: 0 0 8px rgba(232, 112, 58, 0.6);
}

.floating-relationship {
    color: var(--frost);
    box-shadow: 0 0 18px rgba(143, 199, 232, 0.5);
    text-shadow: 0 0 8px rgba(143, 199, 232, 0.6);
}

.floating-save {
    color: var(--gold);
    box-shadow: 0 0 18px rgba(230, 192, 101, 0.5);
    text-shadow: 0 0 8px rgba(230, 192, 101, 0.6);
}

@keyframes floatUp {
    0% {
        opacity: 0;
        top: 65%;
        transform: translate(-50%, -50%) scale(0.8);
    }
    15% {
        opacity: 1;
        transform: translate(-50%, -50%) scale(1.05);
    }
    100% {
        opacity: 0;
        top: 25%;
        transform: translate(-50%, -50%) scale(1);
    }
}

/* Banish pregnancy select cards */
.banish-abort-card {
    background: rgba(255, 255, 255, 0.03);
    padding: 14px;
    border-radius: 10px;
    margin-bottom: 12px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    border: 1px solid rgba(255, 255, 255, 0.05);
}

/* Custom Alert classes for logs */
.jealousy-alert { color: var(--ember); font-weight: bold; }
.refusal-alert { color: #ff5555; }
.pregnancy-alert { color: var(--ember); font-weight: 800; text-decoration: underline; }
.sober-alert { color: var(--gold); }
.success-log { color: var(--gold); }
.stat-change { color: #ffcc00; }
.save-log { color: var(--frost); }
.status-log { color: var(--amber-soft); font-weight: 600; }

.intro-banner {
    background: rgba(156, 43, 78, 0.05);
    border: 1px solid rgba(156, 43, 78, 0.2);
    border-radius: var(--radius-md);
    padding: 26px;
    margin: 20px 0;
    box-shadow: var(--shadow-glow);
    animation: panelFadeIn 0.4s var(--ease-smooth);
}

.intro-banner h2 {
    font-family: 'Outfit', sans-serif;
    margin-bottom: 12px;
    color: var(--ember);
}

.intro-banner p {
    margin-bottom: 12px;
    font-size: 14px;
}

/* Custom Scrollbars */
::-webkit-scrollbar {
    width: 6px;
    height: 6px;
}
::-webkit-scrollbar-track {
    background: rgba(0, 0, 0, 0.2);
}
::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.1);
    border-radius: 3px;
}
::-webkit-scrollbar-thumb:hover {
    background: var(--ember);
}

/* Epilogue scroll window */
.epilogue-text-box {
    text-align: left;
    max-height: 250px;
    overflow-y: auto;
    background: rgba(0, 0, 0, 0.25);
    padding: 15px;
    border-radius: 8px;
    border: 1px solid rgba(255, 255, 255, 0.05);
    margin: 15px 0;
    font-size: 14px;
}
.epilogue-text-box h3 {
    margin-bottom: 8px;
    color: var(--ember);
}
.epilogue-text-box p {
    margin-bottom: 12px;
}

/* ==========================================================================
   Draw button + hint
   ========================================================================== */
.draw-btn {
    position: relative;
    overflow: hidden;
    font-size: 15px !important;
    padding: 13px 34px !important;
    letter-spacing: 1.5px;
    text-transform: uppercase;
}

.draw-btn::after {
    content: "";
    position: absolute;
    top: 0; left: -60%;
    width: 40%; height: 100%;
    background: linear-gradient(115deg, transparent, rgba(255, 255, 255, 0.4), transparent);
    animation: shineSweep 3.4s ease-in-out infinite;
    pointer-events: none;
}

@keyframes shineSweep {
    0%   { left: -60%; }
    35%  { left: 130%; }
    100% { left: 130%; }
}

.draw-btn.drawing {
    opacity: 0.6;
    pointer-events: none;
}

.draw-hint {
    font-size: 11.5px;
    color: var(--text-dim);
    letter-spacing: 0.4px;
    text-align: center;
    max-width: 230px;
}

/* ==========================================================================
   Tide phase indicator (header nautical mechanic)
   ========================================================================== */
.tide-indicator {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 14px 6px 10px;
    border-radius: 30px;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.08);
    transition: border-color 0.3s ease, box-shadow 0.3s ease;
}

.tide-indicator:hover {
    border-color: var(--tide-tint, var(--frost));
    box-shadow: 0 0 16px color-mix(in srgb, var(--tide-tint, var(--frost)) 30%, transparent);
}

.tide-glyph {
    font-size: 18px;
    filter: drop-shadow(0 0 6px var(--tide-tint, var(--frost)));
    animation: tideBob 3s ease-in-out infinite;
}

@keyframes tideBob {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-2px); }
}

.tide-info {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 130px;
}

.tide-phase-name {
    font-family: 'Cinzel', serif;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 1px;
    color: var(--tide-tint, var(--frost));
    text-shadow: 0 0 10px color-mix(in srgb, var(--tide-tint, var(--frost)) 45%, transparent);
    transition: color 0.5s ease;
}

.tide-track {
    height: 5px;
    border-radius: 4px;
    background: rgba(255, 255, 255, 0.08);
    overflow: hidden;
}

.tide-fill {
    height: 100%;
    width: 0%;
    border-radius: 4px;
    background: linear-gradient(90deg, var(--frost), var(--tide-tint, var(--wine)));
    box-shadow: 0 0 10px var(--tide-tint, var(--frost));
    transition: width 0.7s var(--ease-smooth), background 0.6s ease;
    position: relative;
    overflow: hidden;
}

.tide-fill::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, transparent, rgba(255,255,255,0.5), transparent);
    width: 40%;
    animation: barShimmer 2.6s linear infinite;
}

.tide-flash {
    animation: tideFlash 1s ease-out;
}

@keyframes tideFlash {
    0% { box-shadow: 0 0 0 rgba(255,255,255,0); }
    30% { box-shadow: 0 0 26px var(--tide-tint, var(--frost)); }
    100% { box-shadow: 0 0 0 rgba(255,255,255,0); }
}

/* ==========================================================================
   Splash badge
   ========================================================================== */
.splash-badge {
    font-family: 'Outfit', sans-serif;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 2px;
    text-transform: uppercase;
    color: #fff;
    padding: 5px 16px;
    border-radius: 30px;
    background: linear-gradient(135deg, var(--wine), var(--ember));
    box-shadow: 0 0 20px rgba(232, 112, 58, 0.4);
    margin-bottom: 8px;
    animation: splashFadeIn 1s var(--ease-smooth) 0.3s both;
}

/* ==========================================================================
   Save / Load Slots Modal (Captain's Logbook)
   ========================================================================== */
.slots-card {
    max-width: 560px;
}

.slots-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin: 20px 0 24px;
    text-align: left;
}

.slot-row {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px 16px;
    border-radius: var(--radius-md);
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid rgba(255, 255, 255, 0.06);
    transition: transform 0.2s var(--ease-pop), border-color 0.2s ease, box-shadow 0.2s ease;
    opacity: 0;
    transform: translateY(8px);
    animation: cardSlideIn 0.4s var(--ease-pop) forwards;
    animation-delay: calc(var(--i, 0) * 0.06s);
}

.slot-row:hover {
    transform: translateY(-2px);
    border-color: rgba(143, 199, 232, 0.35);
    box-shadow: 0 8px 22px rgba(0, 0, 0, 0.35);
}

.slot-medallion {
    flex-shrink: 0;
    width: 46px;
    height: 46px;
    border-radius: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Cinzel', serif;
    font-weight: 700;
    font-size: 20px;
    color: #fff;
    background: linear-gradient(135deg, var(--ember), var(--wine));
    box-shadow: 0 0 16px rgba(232, 112, 58, 0.35);
}

.slot-row.empty .slot-medallion {
    background: rgba(255, 255, 255, 0.05);
    color: var(--text-dim);
    box-shadow: none;
}

.slot-info {
    flex: 1;
    min-width: 0;
}

.slot-title {
    font-family: 'Outfit', sans-serif;
    font-weight: 700;
    font-size: 15px;
    color: var(--text-main);
}

.slot-meta {
    font-size: 11.5px;
    color: var(--text-muted);
    margin-top: 2px;
}

.slot-meta .slot-dot {
    color: var(--frost);
    margin: 0 5px;
}

.slot-timestamp {
    font-size: 10.5px;
    color: var(--text-dim);
    margin-top: 3px;
    font-family: 'JetBrains Mono', 'Courier New', monospace;
}

.slot-actions {
    display: flex;
    flex-direction: column;
    gap: 6px;
    flex-shrink: 0;
}

.slot-btn {
    font-family: 'Outfit', sans-serif;
    font-weight: 700;
    font-size: 11.5px;
    padding: 6px 14px;
    border-radius: 6px;
    cursor: pointer;
    border: 1px solid rgba(255, 255, 255, 0.12);
    background: rgba(255, 255, 255, 0.05);
    color: var(--text-main);
    transition: all 0.2s ease;
}

.slot-btn.primary {
    background: linear-gradient(135deg, var(--ember), var(--wine));
    border: none;
    color: #fff;
}

.slot-btn.primary:hover {
    box-shadow: 0 0 14px rgba(232, 112, 58, 0.5);
    transform: translateY(-1px);
}

.slot-btn.ghost:hover:not(:disabled) {
    border-color: var(--frost);
    color: #fff;
}

.slot-btn.danger {
    color: var(--danger);
    border-color: rgba(229, 73, 63, 0.3);
}

.slot-btn.danger:hover {
    background: rgba(229, 73, 63, 0.15);
    color: #fff;
}

.slot-btn:disabled {
    opacity: 0.35;
    cursor: not-allowed;
}

/* ==========================================================================
   Responsive Layout
   ========================================================================== */
@media (max-width: 980px) {
    #app {
        grid-template-columns: 1fr;
        grid-template-rows: 60px auto 1fr;
        height: auto;
        min-height: 100vh;
    }
    body {
        overflow-y: auto;
        overflow-x: hidden;
        height: auto;
    }
    aside {
        border-right: none;
        border-bottom: 1px solid rgba(255, 255, 255, 0.05);
        max-height: 40vh;
    }
    .play-layout {
        grid-template-columns: 1fr;
    }
    .draw-section {
        margin-bottom: 8px;
    }
    .tide-indicator {
        order: 3;
    }
}

@media (max-width: 560px) {
    header {
        flex-direction: column;
        gap: 10px;
        padding: 12px;
        height: auto;
    }
    #app {
        grid-template-rows: auto auto 1fr;
    }
    .stats-bar {
        flex-wrap: wrap;
        justify-content: center;
    }
    #drawStage {
        width: 230px;
        height: 230px;
    }
    .tide-info {
        min-width: 110px;
    }
}

/* ==========================================================================
   Cinematic scene — now a single <canvas>, see src/scene.js
   ========================================================================== */
#oceanScene {
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    display: block;
}

/* ==========================================================================
   Footage backdrop — body-level, shared by the title screen and the deck.
   Two stacked plates crossfade so a tide change dissolves instead of cutting.
   See src/backdrop.js.
   ========================================================================== */
.bg-video {
    position: fixed;
    inset: 0;
    z-index: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    pointer-events: none;
    opacity: 0;
    /* Graded cross-dissolve between clips. Duration mirrors FADE_MS in
       backdrop.js; the ease-in-out keeps the midpoint of the blend soft so the
       switch reads as a gradient wash rather than a linear cut. */
    transition: opacity 1.4s cubic-bezier(0.45, 0, 0.55, 1);
}

.bg-video.is-front { opacity: 1; }

/* Four clips have to read as five tide phases: this carries the colour the
   footage cannot. Sits above the plates, below #app (z-index 2). */
.bg-tint {
    position: fixed;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    opacity: 0;
    mix-blend-mode: soft-light;
    transition: background 1.4s var(--ease-smooth), opacity 0.9s var(--ease-smooth);
}

body.has-bg-video.bg-in-game .bg-tint { opacity: 0.55; }

/* The dimmest step of the text ramp was verified against the flat --bg-void.
   Footage raises the effective background behind every panel, where it
   measured 3.89:1 — under AA. This step is the same hue, lifted until it
   clears 4.5:1 against the brightest frame of all four clips.
   Custom properties resolve from the nearest ancestor, so this would silently
   outrank the html-level high-contrast ramp; the second rule restores it. */
body.has-bg-video { --text-dim: #a09585; }
html[data-contrast="high"] body.has-bg-video { --text-dim: #c6bdb0; }

/* The canvas and the footage are alternatives, never co-tenants — but the
   hiding happens in scene.js, not here: refreshFromSettings() writes
   canvas.style.display inline, and an inline style beats any rule in this
   sheet. A `body.has-bg-video #oceanScene { display: none }` rule here looks
   right and does nothing. */

/* Let the scene show through the app — but always keep panels readable */
#app { background: transparent; }

/* While the title screen is up, the game must not exist on screen. The title
   backdrop is deliberately translucent so the ocean canvas reads through it —
   which also meant the header and sidebar were showing through. Note this is
   keyed off a body class, NOT #app[aria-hidden]: the settings dialog sets
   aria-hidden on #app for inertness, and that must not blank the game. */
body.is-title #app { display: none; }

/* Opacities are set by contrast, not by taste: footage is far brighter than
   the canvas these were tuned against. At the old 0.62, body text over the
   deck lanterns measured 2.76:1 — under AA. */
main {
    background: linear-gradient(180deg, rgba(9, 8, 16, 0.90), rgba(9, 8, 16, 0.86));
    backdrop-filter: blur(10px);
}

aside {
    background: rgba(8, 7, 14, 0.86);
    backdrop-filter: blur(10px);
}

/* ==========================================================================
   Header gauges (tide + tension) & sound toggle
   ========================================================================== */
.gauges {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.tension-indicator .tide-glyph {
    transition: filter 0.5s ease;
}

.sound-toggle {
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 50%;
    width: 34px;
    height: 34px;
    font-size: 15px;
    cursor: pointer;
    color: var(--text-main);
    transition: transform 0.2s var(--ease-pop), border-color 0.2s ease, box-shadow 0.2s ease;
    display: flex;
    align-items: center;
    justify-content: center;
}

.sound-toggle:hover {
    transform: scale(1.08);
    border-color: var(--frost);
    box-shadow: 0 0 14px rgba(143, 199, 232, 0.35);
}

.sound-toggle.muted {
    opacity: 0.55;
    filter: grayscale(0.6);
}

/* Ease-the-tension action button flavour */
.action-btn.ease-btn {
    color: var(--frost);
    border-color: rgba(143, 199, 232, 0.4);
    background: rgba(143, 199, 232, 0.06);
}
.action-btn.ease-btn:hover:not(:disabled) {
    background: rgba(143, 199, 232, 0.16);
    box-shadow: 0 0 16px rgba(143, 199, 232, 0.35);
}

@media (max-width: 1100px) {
    .tension-indicator { display: none; }
}

/* ==========================================================================
   A11Y PRIMITIVES
   ========================================================================== */
.visually-hidden {
    position: absolute !important;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.skip-link {
    position: fixed;
    top: 12px;
    left: 12px;
    z-index: 9999;
    padding: 12px 22px;
    border-radius: var(--radius-sm);
    background: var(--ember);
    color: #1a0d06;
    font-family: 'Outfit', sans-serif;
    font-weight: 700;
    font-size: 0.875rem;
    text-decoration: none;
    transform: translateY(-160%);
    transition: transform 0.18s var(--ease-smooth);
}
.skip-link:focus { transform: translateY(0); }

/* A single, unmistakable focus ring everywhere. The old sheet had none at all —
   keyboard users had no idea where they were. */
:focus-visible {
    outline: 3px solid var(--focus-ring);
    outline-offset: 3px;
    border-radius: 4px;
}
:focus:not(:focus-visible) { outline: none; }

/* ==========================================================================
   TITLE SCREEN
   --------------------------------------------------------------------------
   Centred, cinematic composition layered over the live ocean canvas.
   Three things carry it: a moonlight sweep across the wordmark, a rippling
   reflection of that wordmark sitting "on the water", and a menu built from
   typography and light instead of boxes.
   ========================================================================== */
#titleScreen {
    position: fixed;
    inset: 0;
    z-index: 5000;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: clamp(20px, 5vw, 72px);
    /* Single source of truth for the wordmark: the strip of water reserved for
       its reflection is derived from this, so the two can never drift apart.
       Bounded by height as well as width — the composition is vertical, so a
       wide-but-short window must not get a wordmark that eats the menu. */
    --wm-size: clamp(2.5rem, min(8vw, 12vh), 7rem);
    /* Left transparent so the ocean canvas remains the fallback backdrop when
       no video plays. The darkening now lives on .title-scrim, which must sit
       ABOVE the video plate but below the type. */
    background: transparent;
    transition: opacity 0.8s var(--ease-smooth), transform 0.8s var(--ease-smooth);
}

.title-scrim {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    background:
        radial-gradient(ellipse 130% 70% at 50% 118%, rgba(232, 112, 58, 0.13), transparent 62%),
        linear-gradient(180deg,
            rgba(4, 5, 10, 0.90) 0%,
            rgba(4, 5, 10, 0.55) 38%,
            rgba(4, 5, 10, 0.62) 68%,
            rgba(4, 5, 10, 0.92) 100%);
}

/* Deliberately lighter than it needs to be for contrast alone. A scrim heavy
   enough to carry the type on its own crushed the footage to near-black and
   defeated the point of having it; the type gets its own shadow instead. */
#titleScreen.has-video .title-scrim {
    background:
        radial-gradient(ellipse 130% 70% at 50% 118%, rgba(232, 112, 58, 0.14), transparent 62%),
        linear-gradient(180deg,
            rgba(4, 5, 10, 0.82) 0%,
            rgba(4, 5, 10, 0.42) 34%,
            rgba(4, 5, 10, 0.52) 62%,
            rgba(4, 5, 10, 0.89) 100%);
}

/* Local legibility for type sitting on footage. Costs nothing visually on the
   plate and buys far more contrast than darkening the whole frame would. */
#titleScreen.has-video .tm-label,
#titleScreen.has-video .tm-meta,
#titleScreen.has-video .tm-idx,
#titleScreen.has-video .title-footnote,
#titleScreen.has-video .title-byline,
#titleScreen.has-video .title-chapter {
    text-shadow:
        0 1px 2px rgba(0, 0, 0, 0.95),
        0 2px 10px rgba(0, 0, 0, 0.85),
        0 0 28px rgba(0, 0, 0, 0.6);
}

#titleScreen.has-video .title-wordmark {
    filter:
        drop-shadow(0 2px 6px rgba(0, 0, 0, 0.85))
        drop-shadow(0 0 70px rgba(232, 112, 58, 0.30));
}

/* The deck lanterns land directly behind the menu column on the `deck` clip,
   dropping plate contrast under the smallest text to 1.7:1. A wide, heavily
   feathered pool of shade fixes that spot without dimming the lanterns at the
   frame edges, which are the best thing in the shot. */
#titleScreen.has-video .title-menu { position: relative; }

#titleScreen.has-video .title-menu::before {
    content: "";
    position: absolute;
    inset: -44px -150px;
    z-index: -1;
    pointer-events: none;
    background: radial-gradient(ellipse at center,
        rgba(4, 5, 10, 0.84) 0%,
        rgba(4, 5, 10, 0.70) 55%,
        rgba(4, 5, 10, 0.44) 75%,
        rgba(4, 5, 10, 0.16) 90%,
        transparent 100%);
}

#titleScreen.is-leaving {
    opacity: 0;
    transform: scale(1.05);
    pointer-events: none;
}

/* Soft moon high on the right — the light source everything else answers to. */
.title-moon {
    position: absolute;
    z-index: 2;
    top: -14vh;
    right: -6vw;
    width: min(58vw, 620px);
    aspect-ratio: 1;
    pointer-events: none;
    background: radial-gradient(circle at 50% 50%,
        rgba(214, 232, 248, 0.15) 0%,
        rgba(179, 205, 232, 0.07) 34%,
        transparent 68%);
    animation: moonDrift 24s ease-in-out infinite;
}

.title-vignette {
    position: absolute;
    inset: 0;
    z-index: 3;
    pointer-events: none;
    box-shadow: inset 0 0 clamp(90px, 18vw, 260px) rgba(0, 0, 0, 0.85);
}

.title-inner {
    position: relative;
    z-index: 4;
    width: min(660px, 100%);
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
}

/* --- Emblem: small caps flanked by hairlines --- */
/* --- Wordmark + its reflection --- */
.title-mark {
    position: relative;
    /* Reserves the strip of water the reflection falls onto. The mask below
       fades the reflection out by ~42% of its height, so half the wordmark
       size always clears it. */
    margin-bottom: calc(var(--wm-size) * 0.5);
    animation: wordmarkIn 1.4s var(--ease-smooth) 0.22s both;
}

.title-wordmark,
.title-reflection {
    font-family: 'Cinzel', serif;
    font-weight: 800;
    font-size: var(--wm-size);
    line-height: 0.94;
    letter-spacing: 0.015em;
    white-space: nowrap;
}

.title-wordmark {
    /* Cold moonlight, a hot ember band, cold again — the band travels. */
    background: linear-gradient(100deg,
        #7c8ea6 0%,
        #c9dcec 20%,
        #fff6e8 32%,
        #ffd9a3 40%,
        #e8a05a 48%,
        #c9dcec 68%,
        #7c8ea6 100%);
    background-size: 280% 100%;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
    filter: drop-shadow(0 0 70px rgba(232, 112, 58, 0.30));
    animation: moonSweep 12s ease-in-out infinite;
}

.title-reflection {
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    /* Mirror in place: origin must be the centre, or the flip lifts the
       reflection up over the wordmark instead of laying it below. */
    transform: scaleY(-1);
    transform-origin: 50% 50%;
    color: rgba(178, 205, 232, 0.26);
    filter: blur(2.5px);
    pointer-events: none;
    /* Mask lives in un-flipped local space: the local BOTTOM ends up adjacent
       to the wordmark once scaleY(-1) is applied, so that is the opaque end.
       It dies out by ~45% so the reflection never reaches the divider. */
    -webkit-mask-image: linear-gradient(to bottom, transparent 58%, rgba(0, 0, 0, 0.30) 78%, rgba(0, 0, 0, 0.82) 100%);
    mask-image: linear-gradient(to bottom, transparent 58%, rgba(0, 0, 0, 0.30) 78%, rgba(0, 0, 0, 0.82) 100%);
    animation: waterWobble 7s ease-in-out infinite;
}

/* --- Divider: hairline · diamond · hairline --- */
/* --- Menu: typography and light, no cards --- */
.title-menu {
    width: min(480px, 100%);
    /* Last holder of the gap under the wordmark, after the tagline and the
       divider that used to sit here both came out. */
    margin-top: clamp(24px, 4.5vh, 40px);
    display: flex;
    flex-direction: column;
    gap: 2px;
    animation: titleIn 1s var(--ease-smooth) 0.75s both;
}

.title-menu-btn {
    position: relative;
    display: grid;
    grid-template-columns: 30px 1fr 22px;
    align-items: center;
    gap: 14px;
    padding: 12px 18px;
    border: 0;
    border-radius: 10px;
    background: transparent;
    color: var(--text-muted);
    text-align: left;
    font: inherit;
    cursor: pointer;
    isolation: isolate;
    transition: color 0.25s var(--ease-smooth), transform 0.25s var(--ease-smooth);
}

/* Light bleeding in from the left edge on hover/focus. */
.title-menu-btn::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    background: linear-gradient(90deg,
        rgba(232, 112, 58, 0.20) 0%,
        rgba(156, 43, 78, 0.10) 38%,
        transparent 82%);
    opacity: 0;
    transition: opacity 0.25s var(--ease-smooth);
}

/* The ember bar that grows along the left edge. */
.title-menu-btn::after {
    content: "";
    position: absolute;
    left: 0;
    top: 50%;
    width: 2px;
    height: 62%;
    border-radius: 2px;
    background: linear-gradient(180deg, var(--amber), var(--ember), var(--wine));
    box-shadow: 0 0 12px rgba(232, 112, 58, 0.8);
    transform: translateY(-50%) scaleY(0);
    transition: transform 0.28s var(--ease-pop);
}

.title-menu-btn:hover:not(:disabled),
.title-menu-btn:focus-visible {
    color: var(--text-main);
    transform: translateX(5px);
}
.title-menu-btn:hover:not(:disabled)::before,
.title-menu-btn:focus-visible::before { opacity: 1; }
.title-menu-btn:hover:not(:disabled)::after,
.title-menu-btn:focus-visible::after { transform: translateY(-50%) scaleY(1); }

.title-menu-btn.is-primary { color: var(--text-main); }
.title-menu-btn.is-primary::before { opacity: 0.55; }
.title-menu-btn.is-primary::after { transform: translateY(-50%) scaleY(1); }

.title-menu-btn:disabled {
    opacity: 0.34;
    cursor: not-allowed;
}

/* --- Outbound links: web and Patreon ---
   The main menu is deliberately card-less typography. These two go the other
   way — bordered pills, an icon each — precisely so they never read as a fourth
   and fifth way to start playing. */
.title-links {
    width: min(480px, 100%);
    margin-top: clamp(18px, 3vh, 28px);
    padding-top: clamp(14px, 2.4vh, 20px);
    border-top: 1px solid var(--border-soft);
    animation: titleIn 1s var(--ease-smooth) 0.85s both;
}

.title-byline {
    margin-bottom: 10px;
    padding-left: 2px;
    font-size: 0.6875rem;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--text-dim);
}
.title-byline strong {
    font-weight: 600;
    color: var(--gold);
    letter-spacing: 0.18em;
}

.title-links-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
}

.title-link {
    position: relative;
    display: grid;
    grid-template-columns: 26px 1fr 14px;
    align-items: center;
    gap: 10px;
    padding: 11px 13px;
    border: 1px solid var(--border-soft);
    border-radius: 12px;
    background: rgba(255, 255, 255, 0.03);
    color: var(--text-muted);
    text-decoration: none;
    overflow: hidden;
    transition: border-color 0.25s var(--ease-smooth),
                background 0.25s var(--ease-smooth),
                color 0.25s var(--ease-smooth),
                transform 0.25s var(--ease-pop);
}

.title-link:hover,
.title-link:focus-visible {
    transform: translateY(-2px);
    border-color: rgba(230, 192, 101, 0.45);
    background: rgba(255, 255, 255, 0.06);
    color: var(--text-main);
}

/* Patreon is the ask, so it carries the warm fill and the only glow. */
.title-link.is-support {
    border-color: rgba(232, 112, 58, 0.38);
    background: linear-gradient(120deg,
        rgba(232, 112, 58, 0.16),
        rgba(156, 43, 78, 0.10));
    color: var(--text-main);
}
.title-link.is-support:hover,
.title-link.is-support:focus-visible {
    border-color: rgba(232, 112, 58, 0.75);
    background: linear-gradient(120deg,
        rgba(232, 112, 58, 0.28),
        rgba(156, 43, 78, 0.18));
    box-shadow: 0 6px 22px rgba(232, 112, 58, 0.22);
}

.tl-icon {
    width: 26px;
    height: 26px;
    padding: 4px;
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.05);
    fill: none;
    stroke: var(--gold);
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
    opacity: 0.85;
    transition: opacity 0.25s var(--ease-smooth);
}
.title-link:hover .tl-icon,
.title-link:focus-visible .tl-icon { opacity: 1; }

/* The heart reads as a shape, not an outline. */
.title-link.is-support .tl-icon {
    background: rgba(232, 112, 58, 0.14);
    fill: var(--ember);
    stroke: none;
}

.tl-text {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
}

.tl-label {
    font-family: 'Outfit', sans-serif;
    font-weight: 600;
    font-size: 0.8125rem;
    letter-spacing: 0.01em;
    color: inherit;
    /* Long enough to wrap on a narrow rail; a domain should never do that. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.tl-meta {
    font-size: 0.6875rem;
    color: var(--text-dim);
}

.tl-arrow {
    font-size: 0.75rem;
    color: var(--gold);
    opacity: 0.55;
    transition: opacity 0.25s var(--ease-smooth), transform 0.25s var(--ease-pop);
}
.title-link:hover .tl-arrow,
.title-link:focus-visible .tl-arrow {
    opacity: 1;
    transform: translate(2px, -2px);
}

.tm-idx {
    font-family: 'Cinzel', serif;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    color: var(--gold);
    opacity: 0.65;
    text-align: center;
    transition: opacity 0.25s var(--ease-smooth);
}
.title-menu-btn:hover:not(:disabled) .tm-idx,
.title-menu-btn:focus-visible .tm-idx,
.title-menu-btn.is-primary .tm-idx { opacity: 1; }

.tm-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.tm-label {
    font-family: 'Outfit', sans-serif;
    font-weight: 600;
    font-size: 0.9375rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
}

.tm-meta {
    font-size: 0.8125rem;
    letter-spacing: 0.01em;
    /* --text-dim measured 2.87:1 over the lit deck footage — under AA. This
       ramp step clears it with room to spare on all four clips. */
    color: var(--text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
}

.tm-arrow {
    font-size: 1rem;
    color: var(--ember);
    opacity: 0;
    transform: translateX(-6px);
    transition: opacity 0.25s var(--ease-smooth), transform 0.25s var(--ease-pop);
}
.title-menu-btn:hover:not(:disabled) .tm-arrow,
.title-menu-btn:focus-visible .tm-arrow {
    opacity: 1;
    transform: translateX(0);
}

/* --- Footer rail --- */
.title-foot {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 4;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 18px clamp(20px, 5vw, 46px);
    border-top: 1px solid rgba(255, 255, 255, 0.05);
    animation: titleIn 1s var(--ease-smooth) 0.95s both;
}

.title-footnote,
.title-chapter {
    font-size: 0.75rem;
    color: var(--text-dim);
}

.title-chapter {
    font-family: 'Cinzel', serif;
    letter-spacing: 0.24em;
    text-transform: uppercase;
}

.title-footnote kbd {
    display: inline-block;
    padding: 2px 7px;
    border: 1px solid var(--border-soft);
    border-bottom-width: 2px;
    border-radius: 4px;
    background: rgba(255, 255, 255, 0.05);
    font-family: inherit;
    font-size: 0.6875rem;
    color: var(--text-muted);
}

@media (max-width: 620px) {
    .title-chapter { display: none; }
    .title-menu-btn { grid-template-columns: 24px 1fr 0; gap: 10px; }
    .tm-arrow { display: none; }
    /* Side by side, the domain would ellipsis away to nothing. Stack instead,
       and claw back the height the second row costs so the block keeps clear
       of the footer rail. */
    .title-links-row { grid-template-columns: 1fr; gap: 8px; }
    .title-links { margin-top: 14px; padding-top: 12px; }
}

/* Short viewports: the composition is vertical, so height is the binding
   constraint long before width is. Tighten rhythm rather than let the menu
   run under the footer rail. */
@media (max-height: 780px) {
    #titleScreen { padding-block: 32px; }
    .title-menu { margin-top: 22px; }
    .title-menu-btn { padding: 9px 16px; }
    .tm-meta { font-size: 0.75rem; }
    .title-foot { padding-block: 12px; }
    .title-link { padding: 9px 12px; }
}

@media (max-height: 660px) {
    #titleScreen { padding-block: 24px; }
    .title-menu { margin-top: 18px; }
    .title-menu-btn { padding: 7px 16px; }
    .tm-label { font-size: 0.875rem; }
    .tm-meta { font-size: 0.72rem; }
    /* Height is the binding constraint here: the pills keep their labels but
       drop the second line rather than push the menu under the footer rail. */
    .title-links { margin-top: 14px; padding-top: 12px; }
    .title-byline { margin-bottom: 7px; }
    .title-link { padding: 8px 12px; }
    .tl-meta { display: none; }
}

@keyframes titleIn {
    from { opacity: 0; transform: translateY(16px); }
    to   { opacity: 1; transform: none; }
}

@keyframes wordmarkIn {
    from { opacity: 0; transform: translateY(26px) scale(0.96); filter: blur(14px); }
    to   { opacity: 1; transform: none; filter: blur(0); }
}

@keyframes moonSweep {
    0%, 100% { background-position: 118% 50%; }
    50%      { background-position: -18% 50%; }
}

@keyframes waterWobble {
    0%, 100% { transform: scaleY(-1) skewX(0deg)     translateY(0); }
    35%      { transform: scaleY(-1) skewX(0.9deg)   translateY(1.5px); }
    70%      { transform: scaleY(-1) skewX(-0.75deg) translateY(-1px); }
}

@keyframes moonDrift {
    0%, 100% { transform: translate3d(0, 0, 0)      scale(1); }
    50%      { transform: translate3d(-2%, 3%, 0)   scale(1.06); }
}

/* ==========================================================================
   SETTINGS DIALOG
   ========================================================================== */
.settings-overlay {
    position: fixed;
    inset: 0;
    z-index: 6000;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(3, 4, 8, 0.78);
    backdrop-filter: blur(8px);
}
.settings-overlay.is-open { display: flex; }

.settings-card {
    width: min(720px, 100%);
    max-height: min(85vh, 860px);
    display: flex;
    flex-direction: column;
    border: 1px solid var(--border-soft);
    border-radius: var(--radius-lg);
    background: #0d0f18;
    box-shadow: 0 30px 90px rgba(0, 0, 0, 0.7);
    animation: settingsIn 0.32s var(--ease-smooth);
}

@keyframes settingsIn {
    from { opacity: 0; transform: translateY(20px) scale(0.985); }
    to   { opacity: 1; transform: none; }
}

.settings-head {
    position: relative;
    padding: 26px 28px 20px;
    border-bottom: 1px solid var(--border-soft);
}

.settings-head h2 {
    font-family: 'Outfit', sans-serif;
    font-size: 1.375rem;
    font-weight: 700;
    color: var(--text-main);
}

.settings-sub {
    margin-top: 4px;
    font-size: 0.875rem;
    color: var(--text-dim);
}

.settings-close {
    position: absolute;
    top: 20px;
    right: 20px;
    width: 38px;
    height: 38px;
    border: 1px solid var(--border-soft);
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.04);
    color: var(--text-muted);
    font-size: 1.5rem;
    line-height: 1;
    cursor: pointer;
    transition: background 0.2s, color 0.2s;
}
.settings-close:hover { background: rgba(255, 255, 255, 0.1); color: var(--text-main); }

.settings-body {
    overflow-y: auto;
    padding: 8px 28px 20px;
}

.settings-group { padding: 20px 0; border-bottom: 1px solid rgba(255, 255, 255, 0.05); }
.settings-group:last-child { border-bottom: 0; }

.settings-group h3 {
    font-family: 'Outfit', sans-serif;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--amber-soft);
}

.settings-group-hint {
    margin-top: 5px;
    font-size: 0.8125rem;
    color: var(--text-dim);
}

.settings-row {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 24px;
    padding: 15px 0;
}

.settings-label { flex: 1; min-width: 0; }

.settings-label-text {
    display: block;
    font-size: 0.9375rem;
    color: var(--text-main);
}

.settings-help {
    display: block;
    margin-top: 3px;
    font-size: 0.8125rem;
    color: var(--text-dim);
    max-width: 46ch;
}

/* --- Switch --- */
.settings-switch {
    flex-shrink: 0;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
}

.switch-track {
    display: block;
    width: 50px;
    height: 28px;
    padding: 3px;
    border: 1px solid var(--border-soft);
    border-radius: 100px;
    background: rgba(255, 255, 255, 0.06);
    transition: background 0.2s var(--ease-smooth), border-color 0.2s;
}

.switch-thumb {
    display: block;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--text-dim);
    transition: transform 0.22s var(--ease-pop), background 0.22s;
}

.settings-switch.is-on .switch-track {
    background: var(--ember);
    border-color: var(--ember);
}
.settings-switch.is-on .switch-thumb {
    transform: translateX(22px);
    background: #fff;
}

/* --- Segmented --- */
.settings-segmented {
    flex-shrink: 0;
    display: flex;
    padding: 3px;
    border: 1px solid var(--border-soft);
    border-radius: 100px;
    background: rgba(255, 255, 255, 0.04);
}

.seg-btn {
    padding: 7px 15px;
    border: 0;
    border-radius: 100px;
    background: none;
    color: var(--text-muted);
    font: inherit;
    font-size: 0.8125rem;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.2s, color 0.2s;
}
.seg-btn:hover { color: var(--text-main); }
.seg-btn.is-on {
    background: var(--ember);
    color: #1a0d06;
    font-weight: 600;
}

/* --- Slider --- */
.settings-slider {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 14px;
}

.settings-slider input[type="range"] {
    width: 160px;
    accent-color: var(--ember);
    cursor: pointer;
}

.slider-value {
    min-width: 4ch;
    font-family: 'Outfit', sans-serif;
    font-size: 0.875rem;
    font-variant-numeric: tabular-nums;
    color: var(--text-main);
}

.settings-foot {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 18px 28px;
    border-top: 1px solid var(--border-soft);
}

.settings-btn {
    padding: 11px 26px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border-soft);
    font: inherit;
    font-family: 'Outfit', sans-serif;
    font-weight: 600;
    font-size: 0.875rem;
    cursor: pointer;
    transition: background 0.2s, border-color 0.2s;
}
.settings-btn.ghost { background: none; color: var(--text-muted); }
.settings-btn.ghost:hover { background: rgba(255, 255, 255, 0.06); color: var(--text-main); }
.settings-btn.primary { background: var(--ember); border-color: var(--ember); color: #1a0d06; }
.settings-btn.primary:hover { background: var(--ember-soft); }

@media (max-width: 600px) {
    .settings-row { flex-direction: column; align-items: stretch; gap: 12px; }
    .settings-slider input[type="range"] { width: 100%; }
}

/* ==========================================================================
   ACCESSIBILITY PREFERENCE LAYER
   Driven by data-* attributes that settings.js writes onto <html>.
   ========================================================================== */

/* --- Motion ------------------------------------------------------------- */
html[data-motion="reduced"] *,
html[data-motion="reduced"] *::before,
html[data-motion="reduced"] *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 120ms !important;
}

html[data-motion="none"] *,
html[data-motion="none"] *::before,
html[data-motion="none"] *::after {
    animation: none !important;
    transition: none !important;
    scroll-behavior: auto !important;
}

/* Effects that exist purely to move: strip them rather than speed them up. */
html[data-motion="reduced"] .title-menu-btn:hover,
html[data-motion="none"] .title-menu-btn:hover,
html[data-motion="reduced"] .title-link:hover,
html[data-motion="none"] .title-link:hover { transform: none; }

/* Without the sweep the wordmark would freeze on the cold tail of its gradient.
   Park the warm band across the middle instead, so it still reads as lit. */
html[data-motion="reduced"] .title-wordmark,
html[data-motion="none"] .title-wordmark { background-position: 50% 50%; }

html[data-motion="none"] .title-moon { display: none; }

html[data-shake="off"] #app,
html[data-shake="off"] .modal-card { animation-name: none !important; }

html[data-flashes="off"] #flashOverlay,
html[data-flashes="off"] #confettiLayer { display: none !important; }

/* --- Contrast ----------------------------------------------------------- */
html[data-contrast="high"] {
    --text-main: #ffffff;
    --text-muted: #e4ddd2;
    --text-dim: #c6bdb0;
    --border-soft: rgba(255, 255, 255, 0.35);
    --card-bg: rgba(8, 8, 12, 0.96);
    --card-bg-solid: #06070c;
    --focus-ring: #ffd28a;
}

/* Translucency is the enemy of contrast — make every surface opaque. */
html[data-contrast="high"] main,
html[data-contrast="high"] aside,
html[data-contrast="high"] .settings-card,
html[data-contrast="high"] .modal-card {
    background: #06070c !important;
    backdrop-filter: none !important;
}

html[data-contrast="high"] #oceanScene { opacity: 0.32; }

html[data-contrast="high"] .nav-btn,
html[data-contrast="high"] .action-btn,
html[data-contrast="high"] .tab-btn,
html[data-contrast="high"] .title-menu-btn,
html[data-contrast="high"] .title-link,
html[data-contrast="high"] .seg-btn {
    border: 1px solid rgba(255, 255, 255, 0.45);
}

html[data-contrast="high"] :focus-visible { outline-width: 4px; }

/* --- Typography --------------------------------------------------------- */
/* The evidence for dyslexia support is strongest for generous letter, word and
   line spacing; the typeface itself matters less. We do both. */
html[data-dyslexia="on"] body,
html[data-dyslexia="on"] button,
html[data-dyslexia="on"] input,
html[data-dyslexia="on"] select {
    font-family: "OpenDyslexic", "Atkinson Hyperlegible", Verdana, Tahoma, sans-serif !important;
    letter-spacing: 0.045em;
    word-spacing: 0.14em;
}

html[data-dyslexia="on"] .title-wordmark,
html[data-dyslexia="on"] h1,
html[data-dyslexia="on"] h2 {
    font-family: Verdana, Tahoma, sans-serif !important;
}

/* Long-form text should never carry display letter-spacing. */
html[data-dyslexia="on"] .title-byline,
html[data-dyslexia="on"] .aside-title { letter-spacing: 0.08em; }

html[data-spacing="tight"]  { --line-base: 1.4; }
html[data-spacing="normal"] { --line-base: 1.6; }
html[data-spacing="loose"]  { --line-base: 1.95; }

body,
.bubble-text,
.narrative-line,
.modal-desc,
.epilogue-text-box,
.settings-help,
.intro-banner p {
    line-height: var(--line-base);
}

html[data-spacing="loose"] .bubble-text,
html[data-spacing="loose"] .narrative-line,
html[data-spacing="loose"] .epilogue-text-box p { margin-bottom: 0.85em; }

html[data-underline="on"] a { text-decoration: underline !important; }
/* The external title entries are anchors dressed as menu rows: underlining the
   whole grid draws a rule across index, label and arrow alike. Mark the label. */
html[data-underline="on"] .title-link { text-decoration: none !important; }
html[data-underline="on"] .title-link .tl-label { text-decoration: underline; }

/* --- Density ------------------------------------------------------------ */
html[data-density="compact"] .settings-row { padding: 9px 0; }
html[data-density="compact"] .settings-group { padding: 13px 0; }
html[data-density="compact"] .sidebar-player-card { padding: 8px 10px; }
html[data-density="compact"] .panel-content { padding: 14px; }
html[data-density="compact"] .settings-help { display: none; }

/* --- Content ------------------------------------------------------------ */
html[data-blurimages="on"] .scene-visual-img,
html[data-blurimages="on"] .modal-img {
    filter: blur(22px);
    transition: filter 0.25s var(--ease-smooth);
}
html[data-blurimages="on"] .scene-visual-img:hover,
html[data-blurimages="on"] .modal-img:hover,
html[data-blurimages="on"] .visual-image-wrapper:focus-within .scene-visual-img {
    filter: none;
}

/* --- Type scale --------------------------------------------------------- */
/* Expressed in rem so the text-size setting genuinely moves them. */
body { font-size: 1rem; }
.bubble-text     { font-size: 0.9375rem; }
.narrative-line  { font-size: 0.9375rem; }
.modal-desc      { font-size: 0.9375rem; }
.nav-btn,
.action-btn,
.gallery-btn     { font-size: 0.875rem; }
.tab-btn         { font-size: 0.9375rem; }
.stat-pill       { font-size: 0.8125rem; }
.player-name-lbl { font-size: 0.9375rem; }
.epilogue-text-box { font-size: 0.9375rem; }
.persistent-log-entry { font-size: 0.875rem; }

/* Extreme tracking is fine on a 4-word label, painful on a sentence. */
.intro-banner p,
.modal-desc,
.bubble-text { letter-spacing: normal; }

/* ==========================================================================
   PHASE 2 — MECHANICS UI
   ========================================================================== */

/* --- Header pills -------------------------------------------------------- */
/* The two cells that drive decisions get colour; the tallies stay neutral so
   they do not compete with them. */
.stat-pill.stat-sway { background: rgba(230, 192, 101, 0.09); }
.stat-pill.stat-sway .stat-val { color: var(--gold); }
.stat-pill.stat-sway .stat-key { color: rgba(230, 192, 101, 0.72); }

.stat-pill.stat-clock .stat-val { color: var(--frost); }

.stat-pill.stat-clock.is-urgent {
    background: rgba(255, 107, 96, 0.14);
}
.stat-pill.stat-clock.is-urgent .stat-val {
    color: var(--danger);
    animation: urgentPulse 1.6s ease-in-out infinite;
}
.stat-pill.stat-clock.is-urgent .stat-key { color: rgba(255, 107, 96, 0.8); }

@keyframes urgentPulse {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.55; }
}

/* --- Sway panel ---------------------------------------------------------- */
.sway-panel {
    width: 100%;
    margin-top: 14px;
    padding: 14px 16px;
    border: 1px solid rgba(230, 192, 101, 0.22);
    border-radius: var(--radius-md);
    background: rgba(230, 192, 101, 0.05);
}

.sway-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 11px;
}

.sway-title {
    font-family: 'Outfit', sans-serif;
    font-weight: 600;
    font-size: 0.8125rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--gold);
}

.sway-count {
    font-size: 0.8125rem;
    color: var(--text-dim);
}

.sway-row {
    display: flex;
    flex-wrap: wrap;
    gap: 9px;
}

.sway-btn {
    display: flex;
    flex-direction: column;
    gap: 2px;
    align-items: flex-start;
    padding: 10px 16px;
    border: 1px solid var(--border-soft);
    border-radius: var(--radius-sm);
    background: rgba(255, 255, 255, 0.04);
    color: var(--text-main);
    font: inherit;
    cursor: pointer;
    transition: background 0.18s var(--ease-smooth),
                border-color 0.18s var(--ease-smooth),
                transform 0.18s var(--ease-smooth);
}

.sway-btn:hover:not(:disabled) {
    background: rgba(230, 192, 101, 0.12);
    border-color: rgba(230, 192, 101, 0.45);
    transform: translateY(-2px);
}

.sway-btn:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

.sway-btn-label {
    font-family: 'Outfit', sans-serif;
    font-weight: 600;
    font-size: 0.9375rem;
}

.sway-btn-cost {
    font-size: 0.75rem;
    color: var(--text-dim);
}

.sway-warn {
    color: var(--danger);
    font-weight: 600;
}

.sway-cancel { border-style: dashed; }

/* --- Action requirement badges ------------------------------------------ */
.req-badge.req-ok {
    color: var(--gold);
    border-color: rgba(230, 192, 101, 0.4);
}

.action-btn.is-locked { opacity: 0.62; }

/* --- Sidebar: traits, neglect, departure -------------------------------- */
.player-trait-note {
    margin-top: 6px;
    font-size: 0.75rem;
    line-height: 1.4;
    color: var(--text-dim);
    font-style: italic;
}

/* Only rendered once somebody is no longer with who they boarded with, so it
   should read as a status change rather than as more flavour text. */
.player-bond-note {
    margin-top: 6px;
    padding: 4px 8px;
    border-radius: 4px;
    background: rgba(255, 217, 122, 0.10);
    border-left: 2px solid #ffd97a;
    font-size: 0.75rem;
    line-height: 1.4;
    color: #ffe3a6;
}

.player-neglect-note {
    margin-top: 6px;
    padding: 4px 8px;
    border-radius: 4px;
    background: rgba(255, 107, 96, 0.12);
    border-left: 2px solid var(--danger);
    font-size: 0.75rem;
    color: #ffb0a8;
}

.player-departed-note {
    margin-top: 6px;
    padding: 4px 8px;
    border-radius: 4px;
    background: rgba(255, 255, 255, 0.05);
    font-size: 0.75rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-dim);
}

.sidebar-player-card.is-departed {
    opacity: 0.45;
    filter: grayscale(0.7);
}

/* --- Ending confirmation ------------------------------------------------ */
.confirm-warning {
    margin-top: 10px;
    padding: 12px 14px;
    border-radius: var(--radius-sm);
    border-left: 3px solid var(--amber);
    background: rgba(255, 171, 61, 0.1);
    color: var(--amber-soft);
    text-align: left;
}

.third-relation {
    color: var(--text-dim);
    font-size: 0.8125rem;
}

/* ==========================================================================
   THE VOYAGE — survival HUD, sea readout
   ========================================================================== */
.sea-readout .sea-label {
    font-size: 9px;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--text-muted);
    opacity: 0.75;
}
.sea-readout .tide-phase-name { font-style: italic; }

.voyage-hud {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    padding: 6px 12px;
    border-radius: 12px;
    background: linear-gradient(180deg, rgba(10, 16, 26, 0.7), rgba(8, 10, 18, 0.5));
    border: 1px solid rgba(143, 199, 232, 0.16);
    box-shadow: inset 0 0 18px rgba(0, 0, 0, 0.4);
}
.voy-day { font-family: 'Outfit', sans-serif; font-size: 12px; color: var(--text-muted); letter-spacing: 0.04em; }
.voy-day b { color: var(--frost); font-size: 15px; }
.voy-sea { font-size: 11px; font-style: italic; color: var(--text-muted); max-width: 160px; }
.voy-res { display: flex; gap: 8px; }
.vres {
    display: flex; align-items: center; gap: 3px;
    padding: 3px 8px; border-radius: 999px;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.08);
    font-size: 12px;
}
.vres-n { font-weight: 700; color: var(--text-main); }
.vres.is-low { border-color: rgba(255, 90, 90, 0.5); background: rgba(255, 60, 60, 0.12); animation: lowPulse 1.6s ease-in-out infinite; }
@keyframes lowPulse { 0%,100% { opacity: 0.6; } 50% { opacity: 1; } }
.voy-strain { display: flex; gap: 8px; }
.vstrain { display: flex; align-items: center; gap: 4px; }
.vstrain-t { width: 54px; height: 6px; border-radius: 3px; background: rgba(255,255,255,0.1); overflow: hidden; }
.vstrain-t i { display: block; height: 100%; border-radius: 3px; transition: width 0.4s ease; }

@media (max-width: 900px) {
    .voyage-hud { width: 100%; justify-content: space-between; }
    .voy-sea { display: none; }
}

/* Landing-party decision box (reuses .finish-choice-box) */
.landfall-box .lf-intro { color: var(--text-muted); font-size: 13px; margin: 4px 0 12px; }
.landfall-opt {
    display: flex; flex-direction: column; align-items: flex-start;
    text-align: left; gap: 2px; width: 100%; margin-bottom: 8px;
    padding: 11px 16px;
}
.landfall-opt .lf-lbl { font-weight: 700; font-size: 14px; }
.landfall-opt .lf-sub { font-size: 11.5px; color: var(--text-muted); font-weight: 400; }
.landfall-opt:disabled { opacity: 0.4; cursor: not-allowed; }

/* Sidebar: dead crew + mood line */
.sidebar-player-card.is-dead { filter: grayscale(1) brightness(0.6); opacity: 0.7; }
.sidebar-player-card.is-dead .player-avatar { box-shadow: none; }
.player-mood-note {
    font-size: 11px; font-style: italic; color: var(--text-muted);
    margin: 2px 0 6px; opacity: 0.85;
}

/* ==========================================================================
   RELATIONSHIP NETWORK
   ========================================================================== */
.relnet-wrap { display: flex; flex-direction: column; align-items: center; gap: 16px; padding: 8px 0 24px; }
.relnet-hint {
    max-width: 460px; margin: 0; text-align: center;
    font-size: 12px; line-height: 1.55; color: var(--text-muted);
}
.relnet-web {
    /* max-width must be 100%, not a vw value: the panel this lives in has its
       own padding, so 92vw overflowed it on narrow screens. */
    position: relative; width: 460px; max-width: 100%; aspect-ratio: 1 / 1;
    margin: 8px auto 26px;
}
.relnet-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.relnet-node {
    position: absolute; transform: translate(-50%, -50%);
    width: min(84px, 18vw); height: min(84px, 18vw); border-radius: 50%;
    padding: 0; cursor: pointer; background: #10121c;
    border: 3px solid var(--nc, #fff);
    box-shadow: 0 0 0 4px rgba(0,0,0,0.4), 0 6px 20px rgba(0,0,0,0.5);
    transition: transform 0.2s var(--ease-pop), box-shadow 0.2s ease;
    overflow: visible;
}
.relnet-node:hover { transform: translate(-50%, -50%) scale(1.08); }
.relnet-node.is-sel { box-shadow: 0 0 0 4px var(--nc, #fff), 0 0 26px var(--nc, #fff); }
.relnet-node.is-dead { filter: grayscale(1) brightness(0.5); }
.relnet-node.is-gone { opacity: 0.45; filter: grayscale(0.7); }
.relnet-face { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; object-position: center top; display: block; }
/* The spite marker: this person has stopped grieving and started wanting. */
.relnet-flag {
    position: absolute; top: -4px; right: -6px; font-size: 15px;
    filter: drop-shadow(0 1px 3px #000);
}
.relnet-name {
    position: absolute; top: calc(100% + 6px); left: 50%; transform: translateX(-50%);
    display: flex; flex-direction: column; align-items: center; gap: 1px;
    font-size: 12px; font-weight: 700; white-space: nowrap; color: var(--text-main);
    text-shadow: 0 1px 4px #000;
}
.relnet-status {
    font-size: 10px; font-weight: 500; font-style: normal;
    color: var(--text-muted); opacity: 0.9;
}

.relnet-legend {
    display: flex; gap: 8px 16px; flex-wrap: wrap; justify-content: center;
    font-size: 11.5px; color: var(--text-muted); max-width: 520px;
}
.relnet-legend .lg-grp { display: inline-flex; align-items: center; gap: 5px; }
/* An arrow swatch, so the legend says "directed" without needing a caption. */
.relnet-legend i.arrow {
    width: 20px; height: 3px; border-radius: 2px; display: inline-block; position: relative;
}
.relnet-legend i.arrow::after {
    content: ""; position: absolute; right: -1px; top: 50%; transform: translateY(-50%);
    border-left: 6px solid currentColor; border-top: 4px solid transparent;
    border-bottom: 4px solid transparent; color: inherit;
}
.relnet-legend i.arrow { color: inherit; }
.relnet-legend i.ring {
    width: 12px; height: 12px; border-radius: 50%; display: inline-block;
    border: 2.5px solid; background: none;
}
.relnet-legend i.band { width: 18px; height: 6px; border-radius: 3px; display: inline-block; opacity: 0.5; }

.relnet-thoughts {
    width: 100%; max-width: 560px;
    background: var(--card-bg-solid);
    border: 1px solid rgba(255,255,255,0.08);
    border-radius: 16px; padding: 18px 20px;
    box-shadow: 0 14px 40px rgba(0,0,0,0.5);
}
.relnet-th-head { display: flex; align-items: center; gap: 14px; margin-bottom: 12px; }
.relnet-th-head img { width: 56px; height: 56px; border-radius: 50%; object-fit: cover; object-position: center top; border: 2px solid rgba(255,255,255,0.15); }
.relnet-th-name { font-family: 'Outfit', sans-serif; font-size: 19px; font-weight: 700; }
.relnet-th-role { font-size: 11.5px; font-weight: 500; color: var(--text-muted); font-style: normal; }
.relnet-th-mood { font-size: 12.5px; font-style: italic; color: var(--text-muted); }

.relnet-meters { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 18px; margin-bottom: 14px; }
.relnet-meter { min-width: 0; }
.relnet-meter span {
    display: flex; justify-content: space-between; align-items: baseline; gap: 6px;
    font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--text-muted);
}
.relnet-meter span b { font-size: 11.5px; color: var(--text-main); letter-spacing: 0; }
.relnet-meter-track { height: 7px; border-radius: 4px; background: rgba(255,255,255,0.08); overflow: hidden; margin-top: 3px; }
.relnet-meter-track i { display: block; height: 100%; border-radius: 4px; transition: width 0.5s ease; }

.relnet-th-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 9px; }
.relnet-th-list li {
    font-size: 13.5px; line-height: 1.5; color: var(--text-main);
    padding: 8px 12px; border-radius: 10px; background: rgba(255,255,255,0.03);
    border-left: 3px solid rgba(255,255,255,0.14);
}
.relnet-th-list li.tone-warm    { border-left-color: #3ad07a; }
.relnet-th-list li.tone-crush   { border-left-color: #ff5aa8; }
.relnet-th-list li.tone-jealous { border-left-color: #ff5555; }
.relnet-th-list li.tone-anguish { border-left-color: #5aa8ff; }
.relnet-th-list li.tone-cold    { border-left-color: #6b7280; }
.relnet-th-list li.tone-curious { border-left-color: #c9a06a; }
.relnet-th-list li.tone-steady  { border-left-color: #8fc7e8; }
.relnet-th-list li.tone-spite   { border-left-color: #ffd23d; background: rgba(255, 210, 61, 0.06); }

.relnet-foot { margin: 12px 0 0; font-size: 11.5px; color: var(--text-muted); text-align: center; opacity: 0.8; }

/* ---- pair inspector: the same pair read from both ends ---- */
.relnet-pair-head { text-align: center; margin-bottom: 14px; }
.relnet-pair-head h4 { font-family: 'Outfit', sans-serif; font-size: 17px; margin: 0 0 2px; }
.relnet-pair-head p { margin: 0; font-size: 12px; font-style: italic; color: var(--text-muted); }
.relnet-pair-cols { display: grid; grid-template-columns: 1fr; gap: 14px; }
@media (min-width: 520px) { .relnet-pair-cols { grid-template-columns: 1fr 1fr; } }
.relnet-pair-col {
    background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.07);
    border-radius: 12px; padding: 12px 14px;
}
.relnet-pair-col .relnet-meter { margin-bottom: 8px; }
.relnet-pair-dir {
    font-family: 'Outfit', sans-serif; font-weight: 700; font-size: 13px; margin-bottom: 10px;
}
.relnet-pair-dir span { color: var(--text-muted); font-weight: 500; }
.relnet-pair-thought {
    margin: 10px 0 0; font-size: 12.5px; line-height: 1.5; font-style: italic;
    color: var(--text-main); opacity: 0.9;
}
.relnet-back { display: block; margin: 16px auto 0; }

/* A confrontation option is a real fork in the voyage, so it gets more room
   than a plain nav button and its consequence line is part of the label. */
.confront-opt { text-align: left; width: 100%; }
.confront-opt .lf-lbl { font-weight: 700; }
.confront-opt:disabled { opacity: 0.45; cursor: not-allowed; }

/* ==========================================================================
   VOYAGE LOG (achievements)
   ========================================================================== */
.ach-head { text-align: center; color: var(--text-muted); font-size: 13px; margin-bottom: 14px; }
.ach-grid { display: grid; grid-template-columns: 1fr; gap: 10px; }
@media (min-width: 520px) { .ach-grid { grid-template-columns: 1fr 1fr; } }
.ach-card {
    display: flex; align-items: center; gap: 12px;
    padding: 12px 14px; border-radius: 12px;
    background: rgba(255,255,255,0.03);
    border: 1px solid rgba(255,255,255,0.07);
    text-align: left;
}
.ach-card.is-got { background: rgba(58, 208, 122, 0.08); border-color: rgba(58, 208, 122, 0.28); }
.ach-card.is-locked { opacity: 0.6; }
.ach-icon { font-size: 26px; flex-shrink: 0; width: 34px; text-align: center; }
.ach-name { font-family: 'Outfit', sans-serif; font-weight: 700; font-size: 14.5px; }
.ach-desc { font-size: 12px; color: var(--text-muted); }

/* ==========================================================================
   THE CAPTAIN'S LOCKER  (src/locker.js)

   Two states share one stylesheet on purpose: the locked render is the
   unlocked render with focus taken away from it. Nothing is hidden, nothing
   is replaced by an upsell placeholder — the player is looking at the real
   shelf through frosted glass, which is the only version of a teaser that
   does not feel like a lie.
   ========================================================================== */

.lk-head {
    position: relative;
    padding: 4px 0 18px;
    border-bottom: 1px solid var(--border-soft);
    margin-bottom: 22px;
}

.lk-head h2 {
    font-family: 'Cinzel', serif;
    font-size: 1.5rem;
    letter-spacing: 0.5px;
    color: var(--gold);
    margin: 0 0 6px;
}

.lk-sub {
    color: var(--text-muted);
    font-size: 0.92rem;
    margin: 0;
    max-width: 62ch;
}

.lk-stamp {
    position: absolute;
    top: 4px;
    right: 0;
    font-size: 0.7rem;
    letter-spacing: 1.2px;
    color: var(--text-dim);
    border: 1px solid var(--border-soft);
    border-radius: 999px;
    padding: 3px 10px;
    white-space: nowrap;
}

.lk-section { margin-bottom: 34px; }

.lk-section h3 {
    font-family: 'Outfit', sans-serif;
    font-size: 1.05rem;
    color: var(--text-main);
    margin: 0 0 6px;
}

.lk-note {
    color: var(--text-dim);
    font-size: 0.85rem;
    line-height: 1.55;
    margin: 0 0 16px;
    max-width: 70ch;
}

/* ---- the cheats ---- */

.lk-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 12px;
}

.lk-card {
    display: grid;
    grid-template-columns: auto 1fr;
    grid-template-areas: "icon body" "btn btn";
    gap: 12px;
    align-items: start;
    background: var(--card-bg);
    border: 1px solid var(--border-soft);
    border-radius: var(--radius-md);
    padding: 14px;
    transition: border-color 0.25s var(--ease-smooth), transform 0.25s var(--ease-smooth);
}

.lk-card.is-ready { border-color: rgba(230, 192, 101, 0.28); }
.lk-card.is-ready:hover { transform: translateY(-2px); }
.lk-card.is-cooling { opacity: 0.62; }

.lk-icon { grid-area: icon; font-size: 1.55rem; line-height: 1.2; }
.lk-body { grid-area: body; min-width: 0; }

.lk-name {
    font-family: 'Outfit', sans-serif;
    font-weight: 600;
    font-size: 0.98rem;
    color: var(--text-main);
    margin-bottom: 3px;
}

.lk-desc {
    font-size: 0.82rem;
    line-height: 1.5;
    color: var(--text-muted);
}

.lk-cd {
    margin-top: 8px;
    font-size: 0.72rem;
    letter-spacing: 0.6px;
    text-transform: uppercase;
    color: var(--text-dim);
}

.lk-claim {
    grid-area: btn;
    margin-top: 12px;
    width: 100%;
    padding: 9px 14px;
    font-family: 'Outfit', sans-serif;
    font-weight: 600;
    font-size: 0.85rem;
    letter-spacing: 0.4px;
    color: var(--bg-void);
    background: linear-gradient(135deg, var(--gold), var(--amber));
    border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: filter 0.2s var(--ease-smooth);
}

.lk-claim:hover:not(:disabled) { filter: brightness(1.12); }

.lk-claim:disabled {
    background: rgba(255, 255, 255, 0.06);
    color: var(--text-dim);
    cursor: default;
}

/* ---- the shelf ---- */

.lk-shelf {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 10px;
}

.lk-shot {
    position: relative;
    margin: 0;
    border-radius: var(--radius-sm);
    overflow: hidden;
    border: 1px solid var(--border-soft);
    background: var(--bg-deep);
    cursor: pointer;
    aspect-ratio: 4 / 5;
}

.lk-thumb {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 0.35s var(--ease-smooth), filter 0.35s var(--ease-smooth);
}

.lk-shot:not(.is-blurred):hover .lk-thumb { transform: scale(1.05); }

.lk-shot:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 2px;
}

/* The locked state. The blur is heavy enough that no frame is legible and
   light enough that the composition still reads as a real scene. */
.lk-shot.is-blurred .lk-thumb {
    filter: blur(15px) saturate(0.45) brightness(0.62);
    transform: scale(1.15);   /* hides the transparent edge blur leaves behind */
}

.lk-cap {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 16px 8px 7px;
    font-size: 0.72rem;
    line-height: 1.3;
    color: var(--text-main);
    background: linear-gradient(to top, rgba(4, 3, 8, 0.92), transparent);
}

.lk-shot.is-blurred .lk-cap {
    color: var(--text-dim);
    letter-spacing: 0.6px;
    text-transform: uppercase;
    font-size: 0.66rem;
}

.lk-padlock {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: 1.4rem;
    opacity: 0.5;
    pointer-events: none;
}

/* ---- the upsell strip under a locked panel ---- */

.lk-upsell {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    align-items: center;
    justify-content: space-between;
    padding: 18px 20px;
    border-radius: var(--radius-md);
    border: 1px solid rgba(230, 192, 101, 0.22);
    background: linear-gradient(135deg, rgba(230, 192, 101, 0.07), rgba(156, 43, 78, 0.07));
}

.lk-upsell-text { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.lk-upsell-text strong { font-family: 'Outfit', sans-serif; font-size: 0.98rem; color: var(--text-main); }
.lk-upsell-text span { font-size: 0.84rem; color: var(--text-muted); }

.lk-upsell-btn {
    flex: none;
    padding: 10px 20px;
    border-radius: var(--radius-sm);
    background: linear-gradient(135deg, var(--gold), var(--amber));
    color: var(--bg-void);
    font-family: 'Outfit', sans-serif;
    font-weight: 700;
    font-size: 0.86rem;
    text-decoration: none;
    white-space: nowrap;
}

.lk-upsell-btn:hover { filter: brightness(1.12); }

/* ---- the gate + the code prompt ---- */

.lk-gate,
.lk-viewer {
    position: fixed;
    inset: 0;
    z-index: 1200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(4, 3, 8, 0.86);
    backdrop-filter: blur(14px);
    animation: overlayFade 0.3s var(--ease-smooth);
}

.lk-gate-card {
    background: var(--card-bg-solid);
    border: 1px solid rgba(230, 192, 101, 0.22);
    border-radius: var(--radius-lg);
    max-width: 480px;
    width: 100%;
    padding: 30px;
    text-align: center;
    box-shadow: 0 30px 70px rgba(0, 0, 0, 0.5);
    animation: modalSlideUp 0.4s var(--ease-pop) forwards;
}

.lk-gate-glyph { font-size: 2rem; margin-bottom: 10px; }

.lk-gate-card h2 {
    font-family: 'Cinzel', serif;
    font-size: 1.3rem;
    color: var(--gold);
    margin: 0 0 12px;
}

.lk-gate-card p {
    font-size: 0.88rem;
    line-height: 1.6;
    color: var(--text-muted);
    margin: 0 0 16px;
}

.lk-gate-list {
    list-style: none;
    padding: 0;
    margin: 0 0 22px;
    text-align: left;
}

.lk-gate-list li {
    position: relative;
    padding-left: 22px;
    margin-bottom: 9px;
    font-size: 0.84rem;
    line-height: 1.5;
    color: var(--text-muted);
}

.lk-gate-list li::before {
    content: "\25C6";
    position: absolute;
    left: 2px;
    color: var(--gold);
    font-size: 0.7rem;
    top: 2px;
}

.lk-gate-cta {
    display: block;
    padding: 12px 22px;
    border-radius: var(--radius-sm);
    background: linear-gradient(135deg, var(--gold), var(--amber));
    color: var(--bg-void);
    font-family: 'Outfit', sans-serif;
    font-weight: 700;
    font-size: 0.92rem;
    text-decoration: none;
    border: none;
    width: 100%;
    cursor: pointer;
}

.lk-gate-cta:hover { filter: brightness(1.12); }

.lk-gate-back {
    display: block;
    width: 100%;
    margin-top: 10px;
    padding: 10px;
    background: none;
    border: 1px solid var(--border-soft);
    border-radius: var(--radius-sm);
    color: var(--text-muted);
    font-size: 0.84rem;
    cursor: pointer;
}

.lk-gate-back:hover { color: var(--text-main); border-color: rgba(255, 255, 255, 0.18); }

.lk-code-input {
    width: 100%;
    padding: 12px 14px;
    margin-bottom: 10px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border-soft);
    background: rgba(0, 0, 0, 0.35);
    color: var(--text-main);
    font-family: 'Outfit', sans-serif;
    font-size: 1rem;
    letter-spacing: 2px;
    text-align: center;
}

.lk-code-input:focus {
    outline: none;
    border-color: var(--focus-ring);
}

.lk-code-err {
    color: var(--danger) !important;
    font-size: 0.8rem !important;
    margin: 0 0 12px !important;
}

/* ---- the clip viewer ---- */

.lk-viewer-card {
    position: relative;
    max-width: min(900px, 92vw);
    max-height: 88vh;
    border-radius: var(--radius-md);
    overflow: hidden;
    background: #000;
    box-shadow: 0 30px 80px rgba(0, 0, 0, 0.6);
}

.lk-viewer-card video {
    display: block;
    max-width: 100%;
    max-height: 80vh;
}

.lk-viewer-cap {
    padding: 10px 14px;
    font-size: 0.85rem;
    color: var(--text-muted);
    background: var(--bg-deep);
}

.lk-viewer-close {
    position: absolute;
    top: 8px;
    right: 8px;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    border: none;
    background: rgba(0, 0, 0, 0.6);
    color: #fff;
    font-size: 1.4rem;
    line-height: 1;
    cursor: pointer;
}

.lk-viewer-close:hover { background: rgba(0, 0, 0, 0.85); }

/* ---- version stamps around the shell ---- */

.title-version {
    margin-top: 4px;
    font-size: 0.68rem;
    letter-spacing: 1.4px;
    color: var(--text-dim);
    opacity: 0.75;
}

.header-version {
    font-size: 0.62rem;
    letter-spacing: 1px;
    color: var(--text-dim);
    border: 1px solid var(--border-soft);
    border-radius: 999px;
    padding: 2px 8px;
    white-space: nowrap;
    align-self: center;
}

/* The locker tab reads as an aside, not a call to action. */
.tab-btn.tab-locker { color: var(--gold); }
.tab-btn.tab-locker.active { border-bottom-color: var(--gold); }

@media (prefers-reduced-motion: reduce) {
    .lk-card, .lk-thumb, .lk-gate-card { transition: none; animation: none; }
}
